home *** CD-ROM | disk | FTP | other *** search
/ CD BIT 75 / CD BIT 75.iso / Software / SinfoSeguros / MSDE / Setup / SqlRun.cab / sqldmo.sql.24170C3F_A9E4_47C1_8DFE_FD79C2714697 < prev    next >
Encoding:
Text File  |  2002-12-17  |  182.1 KB  |  4,361 lines

  1.  
  2. /**********************************************************************
  3.  * Microsoft SQL Server SQL-DMO scripts, version 8.0.
  4.  * Date created:  3/17/96.
  5.  * Date modified: 7/05/00.
  6.  * Copyright Microsoft Corporation, 1992-2000
  7.  **********************************************************************
  8.  *    This script must be installed for the SQL-DMO (SQLDMO) objects and
  9.  *    the SQL Enterprise Manager to run against a Microsoft SQL Server.
  10.  **********************************************************************/
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29. /* Preprocessor directives, will be blank space in output .sql file. */
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41. /* For fetching from cursor */
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57. /* 8.0, the new UDF object is uning what UDDT has been using */
  58. /* so we have to assing a new value to UDDT, this has to be consistent with the defines in dmo_itf.h */
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.  
  75.  
  76.  
  77.  
  78.  
  79.  
  80.  
  81.  
  82.  
  83.  
  84.  
  85.  
  86.  
  87.  
  88.  
  89.  
  90.  
  91.  
  92.  
  93.  
  94.  
  95.  
  96.  
  97. /* status values for these. */
  98.  
  99.  
  100.  
  101.  
  102.  
  103.  
  104.  
  105. /* bitmask values for same; power(2, DRI_*). */
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121.  
  122.  
  123.  
  124. /* DRI-generated index masks, to apply to sysindexes.status */
  125.  
  126.  
  127.  
  128.  
  129.  
  130.  
  131. /* sysobjects.category bit that indicates this is an MS-internal object. */
  132.  
  133.  
  134. /* sysobjects.category bit for an sp_ that indicates it's a startup proc, or an xp that should ImpersonateClient. */
  135.  
  136.  
  137.  
  138. /* BIT_CLUSTERED indicates the key is clustered. */
  139. /* EXCLUDE REPLICATION value in sysconstraints.status, and system-generated name. */
  140.  
  141.  
  142.  
  143.  
  144.  
  145. /* sysobjects.sysstat bits (lower 4) that mask off the object type. */
  146.  
  147.  
  148. /* bit for DEFAULTS which are really DRI-created. */
  149.  
  150.  
  151. /* bits for sp_MShelpcolumns col_flags - don't conflict with bit_sysgenname for DRIDefaults. */
  152.  
  153.  
  154.  
  155.  
  156.  
  157. /* sysdatabases.category bits */
  158.  
  159.  
  160.  
  161. /* sysobjects.category bits (from ntdbms\object.h) */
  162.  
  163.  
  164.  
  165.  
  166.  
  167.  
  168.  
  169.  
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176.  
  177.  
  178.  
  179. /* The parser can't '|' 0x-prefixed types as it thinks they're binary */
  180.  
  181.  
  182.  
  183.  
  184.  
  185.  
  186.  
  187. /**** daVinci additions ****/
  188.  
  189. /* sp_MStablekeys @flags bitmask param values. */
  190.  
  191.  
  192. /* sp_MShelpindexes @flags bitmask param values. */
  193.  
  194.  
  195. /* sp_MStablechecks @flags bitmask param values. */
  196.  
  197.  
  198.  
  199. /* Descending indices definitions, used in core_sql.cxx, key.cpp, and index.cpp */
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.  
  207.  
  208.  
  209.  
  210.  
  211.  
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218.  
  219.  
  220.  
  221.  
  222.  
  223.  
  224.  
  225. /* Internal #defines for SQLDMO. */
  226.  
  227. /* Current SQLDMO version.  Also must be available to SQLDMO.odl. */
  228. /* #define SQLDMOVERSION_MAJOR             7  */
  229. /* #define SQLDMOVERSION_MINOR             50 */
  230.  
  231.  
  232.  
  233.  
  234.  
  235.  
  236. /* Make sure we use our own; shield SQLDMO from Starfighter changes. */
  237.  
  238.  
  239.  
  240.  
  241.  
  242.  
  243.  
  244. /* Our max name lengths. */
  245. /* !! All lengths retrieved from server must be rounded UP TO THE NEXT 4-bytes. !! */
  246. /* There must be at least one byte more than server max length, for the NULL byte. */
  247.  
  248. /* 7.0 Identifier length has been increased from 30 to 128 characters */
  249.  
  250.  
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268. /* Keep for Replication, but changed to SYSNAME length */
  269.  
  270.  
  271.  
  272.  
  273.  
  274.  
  275.  
  276.  
  277.  
  278.  
  279.  
  280.  
  281.  
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300.  
  301. /* 7.0 */
  302.  
  303.  
  304.  
  305. /* Reserve enough space for [] quoting character, and escape character in identifier */
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326. /* Specail Identifier length for mapping table when scripting from 6.x server, this is the sysname length for 6.x server */
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334. use master
  335. go
  336.  
  337. print ''
  338. print 'Creating SQLDMO stored procedures...'
  339. print ''
  340.  
  341. /************* DUMP THE TRANSACTION LOG **************************************/
  342. /* Comment this out if you don't want your log dumped.  If you rerun this    */
  343. /* script periodically, you will run out of transaction log space.           */
  344. print ''
  345. print 'Dumping transaction log...'
  346. print ''
  347. go
  348. dump tran master with no_log
  349. go
  350. /************* END DUMP THE TRANSACTION LOG **********************************/
  351.  
  352. /********************** Include individual components definitions *********************************/
  353.  
  354.  
  355.  
  356.  
  357.  
  358.  
  359.  
  360.  
  361.  
  362.  
  363.  
  364.  
  365.  
  366.  
  367.  
  368.  
  369.  
  370.  
  371.  
  372.  
  373.  
  374.  
  375.  
  376.  
  377.  
  378.  
  379.  
  380.  
  381.  
  382.  
  383.  
  384.  
  385.  
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.  
  401.  
  402.  
  403.  
  404.  
  405.  
  406. /* From perm.h */
  407.  
  408.  
  409.  
  410.  
  411.  
  412.  
  413.  
  414.  
  415.  
  416.  
  417.  
  418.  
  419.  
  420.  
  421.  
  422. /* Roles */
  423.  
  424.  
  425.  
  426.  
  427.  
  428.  
  429.  
  430.  
  431.  
  432.  
  433.  
  434.  
  435.  
  436.  
  437.  
  438.  
  439.  
  440.  
  441.  
  442. /* File Growth */
  443.  
  444.  
  445. /* Max. Column length */
  446.  
  447.  
  448. /* Default collation, no scripting */
  449.  
  450.  
  451. /********************* Delete existing objects *********************************/
  452. print N''
  453. print N'Deleting existing objects...'
  454. print N''
  455. go
  456.  
  457. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MShelpcolumns')
  458.     drop procedure sp_MShelpcolumns
  459. go
  460. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MShelpindex')
  461.     drop procedure sp_MShelpindex
  462. go
  463. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MShelptype')
  464.     drop procedure sp_MShelptype
  465. go
  466. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSdependencies')
  467.     drop procedure sp_MSdependencies
  468. go
  469. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MStablespace')
  470.     drop procedure sp_MStablespace
  471. go
  472. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSindexspace')
  473.     drop procedure sp_MSindexspace
  474. go
  475. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSuniquename')
  476.     drop procedure sp_MSuniquename
  477. go
  478. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSkilldb')
  479.     drop procedure sp_MSkilldb
  480. go
  481. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSobjectprivs')
  482.     drop procedure sp_MSobjectprivs
  483. go
  484. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSloginmappings')
  485.     drop procedure sp_MSloginmappings
  486. go
  487. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MStablekeys')
  488.     drop procedure sp_MStablekeys
  489. go
  490. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MStablechecks')
  491.     drop procedure sp_MStablechecks
  492. go
  493. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MStablerefs')
  494.     drop procedure sp_MStablerefs
  495. go
  496. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSsettopology')
  497.     drop procedure sp_MSsettopology
  498. go
  499. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSmatchkey')
  500.     drop procedure sp_MSmatchkey
  501. go
  502. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSforeachdb')
  503.     drop procedure sp_MSforeachdb
  504. go
  505. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSforeachtable')
  506.     drop procedure sp_MSforeachtable
  507. go
  508. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSforeach_worker')
  509.     drop procedure sp_MSforeach_worker
  510. go
  511. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSSQLOLE_version')
  512.     drop procedure sp_MSSQLOLE_version
  513. go
  514. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSSQLOLE65_version')
  515.     drop procedure sp_MSSQLOLE65_version
  516. go
  517. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSSQLDMO70_version')
  518.     drop procedure sp_MSSQLDMO70_version
  519. go
  520. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSSQLDMO75_version')
  521.     drop procedure sp_MSSQLDMO75_version
  522. go
  523. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSSQLDMO80_version')
  524.     drop procedure sp_MSSQLDMO80_version
  525. go
  526. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSscriptdatabase')
  527.     drop procedure sp_MSscriptdatabase
  528. go
  529. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSscriptdb_worker')
  530.     drop procedure sp_MSscriptdb_worker
  531. go
  532. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSdbuseraccess')
  533.     drop procedure sp_MSdbuseraccess
  534. go
  535. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSdbuserpriv')
  536.     drop procedure sp_MSdbuserpriv
  537. go
  538. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MShelpfulltextindex')
  539.     drop procedure sp_MShelpfulltextindex
  540. go
  541. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MShelpfulltextscript')
  542.     drop procedure sp_MShelpfulltextscript
  543. go
  544. /* sp_MSqv have been removed, but we want to keep this query, just in case there are left over from previous build */
  545. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSqv')
  546.     drop procedure sp_MSqv
  547. go
  548. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSSetServerProperties')
  549.     drop procedure sp_MSSetServerProperties
  550. go
  551. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSGetServerProperties')
  552.     drop procedure sp_MSGetServerProperties
  553. go
  554. if exists (select * from master.dbo.sysobjects where OBJECTPROPERTY(id, N'IsTableFunction') = 1 and name = N'fn_MSFullText')
  555.     drop function fn_MSFullText
  556. go
  557.  
  558. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSSharedFixedDisk')
  559.     drop procedure sp_MSSharedFixedDisk
  560. go
  561.  
  562.  
  563.  
  564.  
  565. /********************* Create new objects *********************************/
  566.  
  567. /* New validation added for 8.0 */
  568. /* if (@@microsoftversion >= SQL80_MINVERSION) begin                                       */
  569. /*     exec sp_MS_upd_sysobj_category 1                                                       */
  570. /* end else begin                                                                          */
  571. /*     RAISERROR 55555 'You need a released version of SQL 8.0 to run this SQLDMO script'     */
  572. /* end                                                                                     */
  573. if (@@microsoftversion < 0x08000000) begin
  574.     RAISERROR 55555 N'You need SQL Server 2000 to run this SQLDMO script'
  575. end
  576.  
  577. /*******************************************************************************/
  578. print N''
  579. print N'Creating sp_MShelpcolumns'
  580. print N''
  581. go
  582. create procedure sp_MShelpcolumns
  583. @tablename nvarchar(517), @flags int = 0, @orderby nvarchar(10) = null, @flags2 int = 0
  584. as
  585.  
  586.    /* For non-string columns, sp_MShelpcolumns returns the length in syscolumns.length, */
  587.    /* which is defined in BOL as "maximum physical storage length from systypes".       */
  588.    /* For string columns (including types based on string types), sp_MShelpcolumns      */
  589.    /* returns this maximum length in characters (i.e. it returns syscolumns.length      */
  590.    /* adjusted to whether the column is based on char or nchar).                        */
  591.  
  592.    /*** @flags2 added for DaVinci uses.  If the bit isn't set, use 6.5 ***/
  593.    /*** sp_MShelpcolumns '%s', null, 'id', 1                           ***/
  594.  
  595.    create table #sphelpcols
  596.       (
  597.       col_name         nvarchar(128)   COLLATE database_default NOT NULL,
  598.       col_id           int                          NOT NULL,
  599.       col_typename     nvarchar(128)   COLLATE database_default NOT NULL,
  600.       col_len          int                          NOT NULL,
  601.       col_prec         int                          NULL,
  602.       col_scale        int                          NULL,
  603.       col_numtype      smallint                     NOT NULL,  /* For DaVinci to get sp_help-type filtering of prec/scale */
  604.       col_null         bit                          NOT NULL,  /* status & 8 */
  605.       col_identity     bit                          NOT NULL,  /* status & 128 */
  606.       col_defname      nvarchar(257)  COLLATE database_default NULL,      /* fully-qual'd default name, or NULL */
  607.       col_rulname      nvarchar(257)  COLLATE database_default NULL,      /* fully-qual'd rule name, or NULL */
  608.       col_basetypename nvarchar(128)   COLLATE database_default NOT NULL,
  609.       col_flags        int                          NULL,      /* COL_* bits */
  610.  
  611. /* Fix for Raid # 53682 */
  612.       col_seed         nvarchar (40)      COLLATE database_default NULL,
  613. /*       col_seed            numeric (28)      NULL,  */
  614.       col_increment    nvarchar (40)      COLLATE database_default NULL,
  615. /*       col_increment    int                 NULL,  */
  616.  
  617.       col_dridefname   nvarchar(128)   COLLATE database_default NULL,      /* DRI DEFAULT name */
  618.       col_dridefid     int                          NULL,      /* remember the DRI DEFAULT id in syscomments, so we can retrieve it later */
  619.       col_iscomputed   int                          NOT NULL,
  620.       col_objectid     int                          NOT NULL,  /* column object id, need it to get computed text from syscomments */
  621.       col_NotForRepl   bit                          NOT NULL,  /* Not For Replication setting */
  622.       col_fulltext     bit                          NOT NULL,  /* FullTextIndex setting */
  623.       col_AnsiPad      bit                          NULL,      /* Ansi_Padding setting */
  624.       /* following columns are repeating the info from col_defname and col_rulname                  */
  625.       /* because we can not change data in col_defname and col_rulname, since daVinci is using them */
  626.       col_DOwner       nvarchar(128)   COLLATE database_default NULL,      /* non-DRI DEFAULT owner, or NULL */
  627.       col_DName        nvarchar(128)   COLLATE database_default NULL,      /* non-DRI DEFAULT name, or NULL */
  628.       col_ROwner       nvarchar(128)   COLLATE database_default NULL,      /* non-DRI RULE owner, or NULL */
  629.       col_RName        nvarchar(128)   COLLATE database_default NULL,      /* non-DRI RULE name, or NULL */
  630.       col_collation    nvarchar(128)   COLLATE database_default NULL,      /* column level collation, valid for string columns only */
  631.       col_isindexable  int,
  632.       col_language     int,
  633.       )
  634.  
  635. /** For DaVinci **/
  636. /** Use sp_help filtering of precision/scale (only fordecimal/numeric types; else use NULL). **/
  637.  
  638.  
  639.     if @flags is null
  640.         select @flags = 0
  641.     if (@tablename = N'?')
  642.     begin
  643.         print N''
  644.         print N'Usage:  sp_MShelpcolumns @tablename, @flags int = 0'
  645.         print N' where @flags is a bitmask of:'
  646.         print N' 0x0200        = No DRI (ignore Checks, Primary/Foreign/Unique Keys, etc.)'
  647.         print N' 0x0400        = UDDTs --> Base type'
  648.         print N' 0x80000        = TimestampToBinary (convert timestamp cols to binary(8))'
  649.         print N' 0x40000000    = No Identity attribute'
  650.         return 0
  651.     end
  652.  
  653.     declare @objid int
  654.     select @objid = object_id(@tablename)
  655.     if (@objid is null)
  656.     begin
  657.         RAISERROR (15001, -1, -1, @tablename)
  658.         return 1
  659.     end
  660.  
  661.     set nocount on
  662.  
  663.    /* Do not store the computed text in this temp table, because one extra join causes big performance hit */
  664.     /* First load stuff so we can blot off inappropriate info and massage as per @flags */
  665.     insert #sphelpcols
  666.         select c.name, c.colid, st.name,
  667.          case when bt.name in (N'nchar', N'nvarchar') then c.length/2 else c.length end,
  668.             ColumnProperty(@objid, c.name, N'Precision'),
  669.             ColumnProperty(@objid, c.name, N'Scale'),
  670.                 -- col_numtype for DaVinci:  use sp_help-type prec/scale filtering for @flags2 & 1
  671.             case when (@flags2 & 1 <> 0 and bt.name in (N'tinyint',N'smallint',N'decimal',N'int',N'real',N'money',N'float',N'numeric',N'smallmoney',N'bigint'))
  672.                     then 1 else 0 end,
  673.                 -- Nullable
  674.             convert(bit, ColumnProperty(@objid, c.name, N'AllowsNull')),
  675.                 -- Identity
  676.             case when (@flags & 0x40000000 = 0) then convert(bit, ColumnProperty(@objid, c.name, N'IsIdentity')) else 0 end,
  677.                 -- Non-DRI Default (make sure it's not a DRI constraint).
  678.             case when (c.cdefault = 0) then null when (OBJECTPROPERTY(c.cdefault, N'IsDefaultCnst') <> 0) then null else user_name(d.uid) + N'.' + d.name end,
  679.                 -- Non-DRI Rule
  680.             case when (c.domain = 0) then null else user_name(r.uid) + N'.' + r.name end,
  681.                 -- Physical base datatype
  682.             bt.name,
  683.                 -- Initialize flags to whether it's a length-specifiable type, or a numeric type, or 0.
  684.             case when st.name in (N'char',N'varchar',N'binary',N'varbinary',N'nchar',N'nvarchar') then 0x0001
  685.                     when st.name in (N'decimal',N'numeric') then 0x0002
  686.                     else 0 end
  687.                     -- Will be NULL if column is not UniqueIdentifier.
  688.                     + case isnull(ColumnProperty(@objid, c.name, N'IsRowGuidCol'), 0) when 0 then 0 else 0x0008 end,
  689.                 -- Identity seed and increment
  690.  
  691. /* Fix for Raid # 53682 */
  692.             case when (ColumnProperty(@objid, c.name, N'IsIdentity') <> 0) then CONVERT(nvarchar(40), ident_seed(@tablename)) else null end,
  693. /*            case when (ColumnProperty(@objid, c.name, N'IsIdentity') <> 0) then ident_seed(@tablename) else null end,  */
  694.             case when (ColumnProperty(@objid, c.name, N'IsIdentity') <> 0) then CONVERT(nvarchar(40), ident_incr(@tablename)) else null end,
  695. /*            case when (ColumnProperty(@objid, c.name, N'IsIdentity') <> 0) then ident_incr(@tablename) else null end,  */
  696.  
  697.                 -- DRI Default name
  698.             case when (@flags & 0x0200 = 0 and c.cdefault is not null and (OBJECTPROPERTY(c.cdefault, N'IsDefaultCnst') <> 0))
  699.                     then object_name(c.cdefault) else null end,
  700.                 -- DRI Default text, if it does not span multiple rows (if it does, SQLDMO will go get them all).
  701.             case when (@flags & 0x0200 = 0 and c.cdefault is not null and (OBJECTPROPERTY(c.cdefault, N'IsDefaultCnst') <> 0))
  702.                     then t.id else null end,
  703.          c.iscomputed,
  704.          c.id,
  705.                 -- Not For Replication
  706.             convert(bit, ColumnProperty(@objid, c.name, N'IsIdNotForRepl')),
  707.          convert(bit, ColumnProperty(@objid, c.name, N'IsFulltextIndexed')),
  708.          convert(bit, ColumnProperty(@objid, c.name, N'UsesAnsiTrim')),
  709.                 -- Non-DRI Default owner and name
  710.             case when (c.cdefault = 0) then null when (OBJECTPROPERTY(c.cdefault, N'IsDefaultCnst') <> 0) then null else user_name(d.uid) end,
  711.             case when (c.cdefault = 0) then null when (OBJECTPROPERTY(c.cdefault, N'IsDefaultCnst') <> 0) then null else d.name end,
  712.                 -- Non-DRI Rule owner and name
  713.             case when (c.domain = 0) then null else user_name(r.uid) end,
  714.             case when (c.domain = 0) then null else r.name end,
  715.            -- column level collation
  716.          c.collation,
  717.            -- IsIndexable
  718.          ColumnProperty(@objid, c.name, N'IsIndexable'),
  719.          c.language
  720.         from dbo.syscolumns c
  721.                 -- NonDRI Default and Rule filters
  722.             left outer join dbo.sysobjects d on d.id = c.cdefault
  723.             left outer join dbo.sysobjects r on r.id = c.domain
  724.                 -- Fully derived data type name
  725.             join dbo.systypes st on st.xusertype = c.xusertype
  726.                 -- Physical base data type name
  727.             join dbo.systypes bt on bt.xusertype = c.xtype
  728.                 -- DRIDefault text, if it's only one row.
  729.             left outer join dbo.syscomments t on t.id = c.cdefault and t.colid = 1
  730.                     and not exists (select * from dbo.syscomments where id = c.cdefault and colid = 2)
  731.         where c.id = @objid
  732.         order by c.colid
  733.  
  734.     /* Convert any timestamp column to binary(8) if they asked. */
  735.     if (@flags & 0x80000 != 0)
  736.         update #sphelpcols set col_typename = N'binary', col_len = 8, col_flags = col_flags | 0x0001 where col_typename = N'timestamp'
  737.  
  738.     /* Now see what our flags are, if anything. */
  739.     if (@flags is not null and @flags != 0)
  740.     begin
  741.         if (@flags & 0x0400 != 0)
  742.         begin
  743.             /* Track from xusertype --> b.<base>xtype --> u.xusertype in systypes */
  744.             /* First mask off the things we will set.  The convert() awkwardness is */
  745.             /* necessitated by SQLServer's handling of 0x-prefixed values. */
  746.             declare @typeflagmask int select @typeflagmask = (convert(int, 0x0001) + convert(int, 0x0002))
  747.             update #sphelpcols set col_typename = b.name,
  748.                 -- ReInitialize flags to whether it's a length-specifiable type, or a numeric type, or 0.
  749.                 col_flags = col_flags & ~@typeflagmask
  750.                             + case when b.name in (N'char',N'varchar',N'binary',N'varbinary',N'nchar',N'nvarchar') then 0x0001
  751.                                 when b.name in (N'decimal',N'numeric') then 0x0002
  752.                                 else 0 end
  753.             from #sphelpcols c, dbo.systypes n, dbo.systypes b
  754.                 where n.name = col_typename                --// xtype (base type) of name
  755.                     and b.xusertype = n.xtype            --// Map it back to where it's xusertype, to get the name
  756.         end
  757.     end
  758.  
  759.     /* Determine if the column is in the primary key */
  760.     if (@flags & 0x0200 = 0 and (OBJECTPROPERTY(@objid, N'TableHasPrimaryKey') <> 0)) begin
  761.         declare @indid int
  762.         select @indid = indid from dbo.sysindexes i where i.id = @objid and i.status & 0x0800 <> 0
  763.         if (@indid is not null)
  764.             update #sphelpcols set col_flags = col_flags | 0x0004
  765.             from #sphelpcols c, dbo.sysindexkeys i
  766.                 where i.id = @objid and i.indid = @indid and i.colid = c.col_id
  767.     end
  768.  
  769.     /* OK, now put out the data.  @flags2 added for DaVinci; currently only bit 1 (sp_help filtering of prec/scale) is relevant. */
  770.     set nocount off
  771.     if (@orderby is null or @orderby = N'id')
  772.     begin
  773.         select c.col_name, c.col_id, c.col_typename, c.col_len,
  774.                     -- Prec/scale only for numeric/decimal
  775.                 col_prec = case when (col_basetypename in (N'decimal',N'numeric') or (@flags2 & 1 <> 0 and col_numtype & 1 <> 0))
  776.                         then c.col_prec else NULL end,
  777.                 col_scale = case when (col_basetypename in (N'decimal',N'numeric') or (@flags2 & 1 <> 0 and col_numtype & 1 <> 0))
  778.                         then c.col_scale else NULL end,
  779.                 col_basetypename, c.col_defname, c.col_rulname, c.col_null, c.col_identity, c.col_flags,
  780.                c.col_seed,
  781.             c.col_increment, c.col_dridefname, cn.text, c.col_iscomputed, cm.text, c.col_NotForRepl,
  782.             c.col_fulltext, c.col_AnsiPad, c.col_DOwner, c.col_DName, c.col_ROwner, c.col_RName,
  783.             collation = c.col_collation,
  784.             ColType = case when( col_basetypename in (N'image')) then d.FT_COLNAME else NULL end,   /* FullText column name for image column */
  785.             case when ( c.col_isindexable is null ) then 0 else c.col_isindexable end,
  786.             case when ( c.col_language >= 0 ) then c.col_language else -1 end
  787.         from ((#sphelpcols c
  788.       left outer join dbo.syscomments cm on cm.id = c.col_objectid and cm.number = c.col_id) left outer join dbo.syscomments cn on c.col_dridefid is not null and cn.id = c.col_dridefid)
  789.       left outer join (select distinct FT_COLNAME = scol.name, FT_ID = sdep.number from dbo.syscolumns scol, dbo.sysdepends sdep where
  790.                        scol.colid = sdep.depnumber and
  791.                        sdep.deptype = 1 and
  792.                        scol.id = @objid and
  793.                        sdep.depid = @objid and
  794.                        ColumnProperty(scol.id, scol.name, N'IsTypeForFullTextBlob') = 1) as d on c.col_id = d.FT_ID
  795.         order by c.col_id
  796.     end else begin
  797.         select c.col_name, c.col_id, c.col_typename, c.col_len,
  798.                     -- Prec/scale only for numeric/decimal
  799.                 col_prec = case when (col_basetypename in (N'decimal',N'numeric') or (@flags2 & 1 <> 0 and col_numtype & 1 <> 0))
  800.                         then c.col_prec else NULL end,
  801.                 col_scale = case when (col_basetypename in (N'decimal',N'numeric') or (@flags2 & 1 <> 0 and col_numtype & 1 <> 0))
  802.                         then c.col_scale else NULL end,
  803.                 col_basetypename, c.col_defname, c.col_rulname, c.col_null, c.col_identity, c.col_flags,
  804.                c.col_seed,
  805.             c.col_increment, c.col_dridefname, cn.text, c.col_iscomputed, cm.text, c.col_NotForRepl,
  806.             c.col_fulltext, c.col_AnsiPad, c.col_DOwner, c.col_DName, c.col_ROwner, c.col_RName,
  807.             collation = c.col_collation,
  808.             ColType = case when( col_basetypename in (N'image')) then d.FT_COLNAME else NULL end,   /* FullText column name for image column */
  809.             case when ( c.col_isindexable is null ) then 0 else c.col_isindexable end,
  810.             case when ( c.col_language >= 0 ) then c.col_language else -1 end
  811.         from ((#sphelpcols c
  812.       left outer join dbo.syscomments cm on cm.id = c.col_objectid and cm.number = c.col_id) left outer join dbo.syscomments cn on c.col_dridefid is not null and cn.id = c.col_dridefid)
  813.       left outer join (select distinct FT_COLNAME = scol.name, FT_ID = sdep.number from dbo.syscolumns scol, dbo.sysdepends sdep where
  814.                        scol.colid = sdep.depnumber and
  815.                        sdep.deptype = 1 and
  816.                        scol.id = @objid and
  817.                        sdep.depid = @objid and
  818.                        ColumnProperty(sdep.id, scol.name, N'IsTypeForFullTextBlob') = 1) as d on c.col_id = d.FT_ID
  819.         order by c.col_name
  820.     end
  821.  
  822. go
  823. /* End sp_MShelpcolumns */
  824.  
  825. /*******************************************************************************/
  826. print N''
  827. print N'Creating sp_MShelpindex'
  828. print N''
  829. go
  830. create procedure sp_MShelpindex
  831. @tablename nvarchar(517), @indexname nvarchar(258) = null, @flags int = null
  832. as
  833.    /*** @flags added for DaVinci uses.  If the bit isn't set, use 6.5 ***/
  834.    /*** sp_MShelpindex '%s', null, 1                                  ***/
  835.  
  836.  
  837.  
  838.  
  839.     create table #tempID
  840.        (
  841.       cName  nvarchar(132) COLLATE database_default NOT NULL,      /* Index name */
  842.       cInx1  int, cInx2  int, cInx3  int, cInx4  int, cInx5  int, cInx6  int, cInx7  int, cInx8  int,
  843.       cInx9  int, cInx10 int, cInx11 int, cInx12 int, cInx13 int, cInx14 int, cInx15 int, cInx16 int,   /* 1 if DESC  */
  844.       cC1  int, cC2  int, cC3  int, cC4  int, cC5  int, cC6  int, cC7  int, cC8  int,
  845.       cC9  int, cC10 int, cC11 int, cC12 int, cC13 int, cC14 int, cC15 int, cC16 int   /* 1 if Computed column  */
  846.       )
  847.  
  848.    create table #tempID2
  849.       (
  850.       cName     nvarchar(132) COLLATE database_default NOT NULL,      /* Index name */
  851.       cInx      int,                                  /* Combined info */
  852.       cComputed int                                   /* 1 if on computed column(s) */
  853.       )
  854.  
  855.    /* @flags is for daVinci */
  856.    if (@flags is null)
  857.       select @flags = 0
  858.  
  859.    set nocount on
  860.    insert #tempID
  861.       select i.name,
  862.       indexkey_property(object_id(@tablename), i.indid, 1, N'isdescending'),
  863.       indexkey_property(object_id(@tablename), i.indid, 2, N'isdescending'),
  864.       indexkey_property(object_id(@tablename), i.indid, 3, N'isdescending'),
  865.       indexkey_property(object_id(@tablename), i.indid, 4, N'isdescending'),
  866.       indexkey_property(object_id(@tablename), i.indid, 5, N'isdescending'),
  867.       indexkey_property(object_id(@tablename), i.indid, 6, N'isdescending'),
  868.       indexkey_property(object_id(@tablename), i.indid, 7, N'isdescending'),
  869.       indexkey_property(object_id(@tablename), i.indid, 8, N'isdescending'),
  870.       indexkey_property(object_id(@tablename), i.indid, 9, N'isdescending'),
  871.       indexkey_property(object_id(@tablename), i.indid, 10, N'isdescending'),
  872.       indexkey_property(object_id(@tablename), i.indid, 11, N'isdescending'),
  873.       indexkey_property(object_id(@tablename), i.indid, 12, N'isdescending'),
  874.       indexkey_property(object_id(@tablename), i.indid, 13, N'isdescending'),
  875.       indexkey_property(object_id(@tablename), i.indid, 14, N'isdescending'),
  876.       indexkey_property(object_id(@tablename), i.indid, 15, N'isdescending'),
  877.       indexkey_property(object_id(@tablename), i.indid, 16, N'isdescending'),
  878.       columnproperty(object_id(@tablename), index_col(@tablename, i.indid, 1), N'IsComputed'),
  879.       columnproperty(object_id(@tablename), index_col(@tablename, i.indid, 2), N'IsComputed'),
  880.       columnproperty(object_id(@tablename), index_col(@tablename, i.indid, 3), N'IsComputed'),
  881.       columnproperty(object_id(@tablename), index_col(@tablename, i.indid, 4), N'IsComputed'),
  882.       columnproperty(object_id(@tablename), index_col(@tablename, i.indid, 5), N'IsComputed'),
  883.       columnproperty(object_id(@tablename), index_col(@tablename, i.indid, 6), N'IsComputed'),
  884.       columnproperty(object_id(@tablename), index_col(@tablename, i.indid, 7), N'IsComputed'),
  885.       columnproperty(object_id(@tablename), index_col(@tablename, i.indid, 8), N'IsComputed'),
  886.       columnproperty(object_id(@tablename), index_col(@tablename, i.indid, 9), N'IsComputed'),
  887.       columnproperty(object_id(@tablename), index_col(@tablename, i.indid, 10), N'IsComputed'),
  888.       columnproperty(object_id(@tablename), index_col(@tablename, i.indid, 11), N'IsComputed'),
  889.       columnproperty(object_id(@tablename), index_col(@tablename, i.indid, 12), N'IsComputed'),
  890.       columnproperty(object_id(@tablename), index_col(@tablename, i.indid, 13), N'IsComputed'),
  891.       columnproperty(object_id(@tablename), index_col(@tablename, i.indid, 14), N'IsComputed'),
  892.       columnproperty(object_id(@tablename), index_col(@tablename, i.indid, 15), N'IsComputed'),
  893.       columnproperty(object_id(@tablename), index_col(@tablename, i.indid, 16), N'IsComputed')
  894.       from dbo.sysindexes i
  895.       where id = object_id(@tablename) and i.indid > 0 and i.indid < 255
  896.       and (@indexname is null or i.name = @indexname)
  897.       and (indexkey_property(object_id(@tablename), i.indid, 1, N'isdescending') is not null)
  898.       and (i.name is not null)
  899.       order by i.indid
  900.  
  901.       /* Construct the bit */
  902.       declare @idx int, @isComputed int
  903.       declare @Name nvarchar(132)
  904.       declare @Inx_1 int, @Inx_2 int, @Inx_3 int, @Inx_4 int, @Inx_5 int, @Inx_6 int, @Inx_7 int, @Inx_8 int
  905.       declare @Inx_9 int, @Inx_10 int, @Inx_11 int, @Inx_12 int, @Inx_13 int, @Inx_14 int, @Inx_15 int, @Inx_16 int
  906.       declare @C_1 int, @C_2 int, @C_3 int, @C_4 int, @C_5 int, @C_6 int, @C_7 int, @C_8 int
  907.       declare @C_9 int, @C_10 int, @C_11 int, @C_12 int, @C_13 int, @C_14 int, @C_15 int, @C_16 int
  908.       declare hC cursor global for select * from #tempID
  909.       open hC
  910.       fetch next from hC into @Name, @Inx_1, @Inx_2, @Inx_3, @Inx_4, @Inx_5, @Inx_6, @Inx_7, @Inx_8,
  911.                               @Inx_9, @Inx_10, @Inx_11, @Inx_12, @Inx_13, @Inx_14, @Inx_15, @Inx_16,
  912.                               @C_1, @C_2, @C_3, @C_4, @C_5, @C_6, @C_7, @C_8,
  913.                               @C_9, @C_10, @C_11, @C_12, @C_13, @C_14, @C_15, @C_16
  914.       while (@@FETCH_STATUS = 0)
  915.          begin
  916.          /* descending? */
  917.          select @idx = 0x0000
  918.          select @idx = (case when (@Inx_1 = 1) then @idx | 0x0001 else @idx end), @idx = (case when (@Inx_2 = 1) then @idx | 0x0002 else @idx end), @idx = (case when (@Inx_3 = 1) then @idx | 0x0004 else @idx end), @idx = (case when (@Inx_4 = 1) then @idx | 0x0008 else @idx end), @idx = (case when (@Inx_5 = 1) then @idx | 0x0010 else @idx end), @idx = (case when (@Inx_6 = 1) then @idx | 0x0020 else @idx end), @idx = (case when (@Inx_7 = 1) then @idx | 0x0040 else @idx end), @idx = (case when (@Inx_8 = 1) then @idx | 0x0080 else @idx end),
  919.                 @idx = (case when (@Inx_9 = 1) then @idx | 0x0100 else @idx end), @idx = (case when (@Inx_10 = 1) then @idx | 0x0200 else @idx end), @idx = (case when (@Inx_11 = 1) then @idx | 0x0400 else @idx end), @idx = (case when (@Inx_12 = 1) then @idx | 0x0800 else @idx end), @idx = (case when (@Inx_13 = 1) then @idx | 0x1000 else @idx end), @idx = (case when (@Inx_14 = 1) then @idx | 0x2000 else @idx end), @idx = (case when (@Inx_15 = 1) then @idx | 0x4000 else @idx end), @idx = (case when (@Inx_16 = 1) then @idx | 0x8000 else @idx end)
  920.          select @isComputed = 0
  921.          select @isComputed = (case when (@C_1 = 1) then @isComputed | 1 else @isComputed end), @isComputed = (case when (@C_2 = 1) then @isComputed | 1 else @isComputed end), @isComputed = (case when (@C_3 = 1) then @isComputed | 1 else @isComputed end), @isComputed = (case when (@C_4 = 1) then @isComputed | 1 else @isComputed end), @isComputed = (case when (@C_5 = 1) then @isComputed | 1 else @isComputed end), @isComputed = (case when (@C_6 = 1) then @isComputed | 1 else @isComputed end), @isComputed = (case when (@C_7 = 1) then @isComputed | 1 else @isComputed end), @isComputed = (case when (@C_8 = 1) then @isComputed | 1 else @isComputed end),
  922.                 @isComputed = (case when (@C_9 = 1) then @isComputed | 1 else @isComputed end), @isComputed = (case when (@C_10 = 1) then @isComputed | 1 else @isComputed end), @isComputed = (case when (@C_11 = 1) then @isComputed | 1 else @isComputed end), @isComputed = (case when (@C_12 = 1) then @isComputed | 1 else @isComputed end), @isComputed = (case when (@C_13 = 1) then @isComputed | 1 else @isComputed end), @isComputed = (case when (@C_14 = 1) then @isComputed | 1 else @isComputed end), @isComputed = (case when (@C_15 = 1) then @isComputed | 1 else @isComputed end), @isComputed = (case when (@C_16 = 1) then @isComputed | 1 else @isComputed end)
  923.          insert #tempID2 select @Name, @idx, @isComputed
  924.          fetch next from hC into @Name, @Inx_1, @Inx_2, @Inx_3, @Inx_4, @Inx_5, @Inx_6, @Inx_7, @Inx_8,
  925.                                  @Inx_9, @Inx_10, @Inx_11, @Inx_12, @Inx_13, @Inx_14, @Inx_15, @Inx_16,
  926.                                  @C_1, @C_2, @C_3, @C_4, @C_5, @C_6, @C_7, @C_8,
  927.                                  @C_9, @C_10, @C_11, @C_12, @C_13, @C_14, @C_15, @C_16
  928.          end
  929.       close hC
  930.       deallocate hC
  931.  
  932.     set nocount off
  933.    if (@flags <> 0)
  934.    begin
  935.    /* daVinci is calling */
  936.       select i.name, i.status, i.indid, i.OrigFillFactor,
  937.       IndCol1 = index_col(@tablename, i.indid, 1),
  938.       IndCol2 = index_col(@tablename, i.indid, 2),
  939.       IndCol3 = index_col(@tablename, i.indid, 3),
  940.       IndCol4 = index_col(@tablename, i.indid, 4),
  941.       IndCol5 = index_col(@tablename, i.indid, 5),
  942.       IndCol6 = index_col(@tablename, i.indid, 6),
  943.       IndCol7 = index_col(@tablename, i.indid, 7),
  944.       IndCol8 = index_col(@tablename, i.indid, 8),
  945.       IndCol9 = index_col(@tablename, i.indid, 9),
  946.       IndCol10 = index_col(@tablename, i.indid, 10),
  947.       IndCol11 = index_col(@tablename, i.indid, 11),
  948.       IndCol12 = index_col(@tablename, i.indid, 12),
  949.       IndCol13 = index_col(@tablename, i.indid, 13),
  950.       IndCol14 = index_col(@tablename, i.indid, 14),
  951.       IndCol15 = index_col(@tablename, i.indid, 15),
  952.       IndCol16 = index_col(@tablename, i.indid, 16)
  953.       , SegName = s.groupname
  954.       , FullTextKey = IndexProperty(object_id(@tablename), i.name, N'IsFulltextKey')
  955.       , Descending = t.cInx
  956.       , Computed = t.cComputed
  957.       , IsTable = OBJECTPROPERTY(object_id(@tablename), N'IsTable')
  958.       from (dbo.sysindexes i inner join
  959.          dbo.sysfilegroups s on
  960.          i.groupid = s.groupid ), #tempID2 t
  961.       where id = object_id(@tablename) and i.indid > 0 and i.indid < 255 and
  962.       (@indexname is null or i.name = @indexname) and
  963.       (INDEXPROPERTY(object_id(@tablename), i.name, N'IsStatistics') <> 1) and
  964.       (INDEXPROPERTY(object_id(@tablename), i.name, N'IsAutoStatistics') <> 1) and
  965.       (INDEXPROPERTY(object_id(@tablename), i.name, N'IsHypothetical') <> 1) and
  966.       i.name = t.cName
  967.       order by i.indid
  968.    end else begin
  969.       /* select (case when (i.status & 0x0040) != 0 then substring(i.name, 9, (datalength(i.name)/2)-17) else i.name end), i.status, i.indid, i.OrigFillFactor, */
  970.       select i.name, i.status, i.indid, i.OrigFillFactor,
  971.       IndCol1 = index_col(@tablename, i.indid, 1),
  972.       IndCol2 = index_col(@tablename, i.indid, 2),
  973.       IndCol3 = index_col(@tablename, i.indid, 3),
  974.       IndCol4 = index_col(@tablename, i.indid, 4),
  975.       IndCol5 = index_col(@tablename, i.indid, 5),
  976.       IndCol6 = index_col(@tablename, i.indid, 6),
  977.       IndCol7 = index_col(@tablename, i.indid, 7),
  978.       IndCol8 = index_col(@tablename, i.indid, 8),
  979.       IndCol9 = index_col(@tablename, i.indid, 9),
  980.       IndCol10 = index_col(@tablename, i.indid, 10),
  981.       IndCol11 = index_col(@tablename, i.indid, 11),
  982.       IndCol12 = index_col(@tablename, i.indid, 12),
  983.       IndCol13 = index_col(@tablename, i.indid, 13),
  984.       IndCol14 = index_col(@tablename, i.indid, 14),
  985.       IndCol15 = index_col(@tablename, i.indid, 15),
  986.       IndCol16 = index_col(@tablename, i.indid, 16)
  987.       , SegName = s.groupname
  988.       , FullTextKey = IndexProperty(object_id(@tablename), i.name, N'IsFulltextKey')
  989.       , Descending = t.cInx
  990.       , Computed = t.cComputed
  991.       , IsTable = OBJECTPROPERTY(object_id(@tablename), N'IsTable')
  992.       from (dbo.sysindexes i inner join
  993.          dbo.sysfilegroups s on
  994.          i.groupid = s.groupid ), #tempID2 t
  995.       where id = object_id(@tablename) and i.indid > 0 and i.indid < 255
  996.       and (@indexname is null or i.name = @indexname) and
  997.       i.name = t.cName
  998.       order by i.indid
  999.       /* order by i.name */
  1000.    end
  1001.  
  1002. go
  1003. /* End sp_MShelpindex */
  1004.  
  1005. /************* DUMP THE TRANSACTION LOG **************************************/
  1006. /* Comment this out if you don't want your log dumped.  If you rerun this    */
  1007. /* script periodically, you will run out of transaction log space.           */
  1008. print N''
  1009. print N'Dumping transaction log...'
  1010. print N''
  1011. go
  1012. dump tran master with no_log
  1013. go
  1014. /************* END DUMP THE TRANSACTION LOG **********************************/
  1015.  
  1016. /*******************************************************************************/
  1017. print N''
  1018. print N'Creating sp_MShelptype'
  1019. print N''
  1020. go
  1021. create procedure sp_MShelptype
  1022. @typename nvarchar(517) = null, @flags nvarchar(10) = null
  1023. as
  1024.  
  1025.     /* Need a temp table so we can ownerqualify nonNULL rules/defaults. */
  1026.     create table #sphelptype (
  1027.         dt_xusertype   int  NULL,
  1028.         dt_basetype    nvarchar(128) COLLATE database_default NULL,
  1029.         dt_rul         int  NULL,
  1030.         dt_def         int  NULL,
  1031.  
  1032.         dt_rulowner    nvarchar(128) COLLATE database_default NULL,
  1033.         dt_rulname     nvarchar(128) COLLATE database_default NULL,
  1034.         dt_defowner    nvarchar(128) COLLATE database_default NULL,
  1035.         dt_defname     nvarchar(128) COLLATE database_default NULL,
  1036.         dt_flags       int  NULL
  1037.     )
  1038.  
  1039.     if (@typename = N'?')
  1040.     begin
  1041.         print N''
  1042.         print N'Usage:  sp_MShelptype @typeename = null, @flags nvarchar(10) = null'
  1043.         print N' where @flags is either:'
  1044.         print N' sdt        = look in system datatypes'
  1045.         print N' uddt      = look in user defined datatypes'
  1046.         print N' null    = look wherever its found'
  1047.         print N''
  1048.         return 0
  1049.     end
  1050.  
  1051.     /* Catch typos... */
  1052.     if (@flags is not null and @flags not in (N'sdt', N'uddt'))
  1053.         select @flags = null
  1054.  
  1055.     /* Find out what type we're gonna be looking in, if they gave us a name. */
  1056.     if (@typename is not null)
  1057.     begin
  1058.         declare @xusertype int
  1059.         select @xusertype = xusertype from dbo.systypes where name = @typename
  1060.         if (@xusertype is not null)
  1061.         begin
  1062.             if (@xusertype < 257)
  1063.             begin
  1064.                 if (@flags is null)
  1065.                     select @flags = N'sdt'
  1066.                 if (@flags != N'sdt')
  1067.                     select @xusertype = null
  1068.             end else begin
  1069.                 if (@flags is null)
  1070.                     select @flags = N'uddt'
  1071.                 if (@flags != N'uddt')
  1072.                     select @xusertype = null
  1073.             end
  1074.         end
  1075.         if (@xusertype is null)
  1076.         begin
  1077.             RAISERROR (15001, -1, -1, @typename)
  1078.             return 1
  1079.         end
  1080.     end
  1081.  
  1082.     /* Now go get the info, depending on the type they gave us. */
  1083.     if (@flags is null or @flags = N'sdt')
  1084.     begin
  1085.         /* Exclude the 'xxxxn' dblib-specific nullable types, and hardcode a check for variable length and numeric usertypes. */
  1086.       /* 7.0 ifvarlen_max returns length for all the datatypes */
  1087.         select     SystemDatatypeName = t.name,
  1088.                 ifvarlen_max = y.length,
  1089.                     -- timestamp allows nulls even though the system tables say it doesn't.
  1090.                 allownulls = case when t.name in (N'timestamp') then 1 else t.allownulls end,
  1091.                 isnumeric = case when t.name in (N'decimal', N'numeric') then 1 else 0 end,
  1092.                 allowidentity = case when t.name in (N'decimal', N'int', N'numeric', N'smallint', N'tinyint', N'bigint') then 1 else 0 end,
  1093.             variablelength = t.variable,
  1094.             max_len = t.length, prec_len = t.prec,
  1095.             collation = t.collation
  1096.          from dbo.systypes t, dbo.systypes y
  1097.          where t.xusertype < 257 and t.name not in (N'datetimn', N'decimaln', N'floatn', N'intn', N'moneyn', N'numericn') and (@typename is null or t.name = @typename)
  1098.          and y.xusertype =* t.xusertype and y.name in ( N'char', N'varchar', N'binary', N'varbinary', N'nchar', N'nvarchar' )
  1099.             order by t.name
  1100.     end
  1101.  
  1102.     if (@flags is null or @flags = N'uddt')
  1103.     begin
  1104.         set nocount on
  1105.         insert #sphelptype (dt_xusertype, dt_basetype, dt_rul, dt_def, dt_flags)
  1106.             select t.xusertype,
  1107.             (select distinct b.name from dbo.systypes b where b.xtype = t.xtype and b.xusertype < 257 and b.name not in (N'sysname', N'timestamp')),
  1108.             t.domain, t.tdefault, 0
  1109.             from dbo.systypes t
  1110.             where t.xusertype > 256 and (@typename is null or t.name = @typename)
  1111.  
  1112.         /* Make a nice, presentable qualified rule/default name for those which are non-null */
  1113.       update #sphelptype set dt_defowner = user_name(d.uid)
  1114.             from #sphelptype c, dbo.sysobjects d where c.dt_def is not null and d.id = c.dt_def
  1115.       update #sphelptype set dt_defname = d.name
  1116.             from #sphelptype c, dbo.sysobjects d where c.dt_def is not null and d.id = c.dt_def
  1117.  
  1118.       update #sphelptype set dt_rulowner = user_name(r.uid)
  1119.             from #sphelptype c, dbo.sysobjects r where c.dt_rul is not null and r.id = c.dt_rul
  1120.       update #sphelptype set dt_rulname =  r.name
  1121.             from #sphelptype c, dbo.sysobjects r where c.dt_rul is not null and r.id = c.dt_rul
  1122.  
  1123.         /* For scripting, set the dt_flags -- these apply to the BASE datatype. */
  1124.         update #sphelptype set dt_flags = dt_flags | 0x0001 where dt_basetype in ( N'char', N'varchar', N'binary', N'varbinary', N'nchar', N'nvarchar')
  1125.         update #sphelptype set dt_flags = dt_flags | 0x0002 where dt_basetype in (N'numeric', N'decimal')
  1126.  
  1127.         set nocount off
  1128.         select distinct UserDatatypeName = t.name,
  1129.                 owner = user_name(t.uid),
  1130.                 -- The subquery fails if the current db is of a different collation from tempdb.
  1131.                 -- Also, not user why the subquery is being used in the 1st place
  1132.                 -- basetypename = (select distinct b.name from dbo.systypes b where b.name = s.dt_basetype),
  1133.                 basetypename = dt_basetype,
  1134.                 defaultname = dt_defname,
  1135.                 rulename = dt_rulname,
  1136.                 tid = t.xusertype,
  1137.                 length = case when s.dt_basetype in (N'char', N'varchar', N'binary', N'varbinary', N'nchar', N'nvarchar') then t.length else 0 end,
  1138.                 nullable = t.allownulls,
  1139.                 dt_prec = case when s.dt_basetype in (N'numeric', N'decimal') then t.prec else null end,
  1140.                 dt_scale = case when s.dt_basetype in (N'numeric', N'decimal') then t.scale else null end,
  1141.                 dt_flags,
  1142.                 allowidentity = case when (s.dt_basetype in (N'decimal', N'int', N'numeric', N'smallint', N'tinyint', N'bigint') and t.scale = 0) then 1 else 0 end,
  1143.             variablelength = t.variable,
  1144.             /* char count for string datatype, byte count for others */
  1145.                 maxlen = case when s.dt_basetype in (N'char', N'varchar', N'binary', N'varbinary', N'nchar', N'nvarchar') then t.prec else t.length end,
  1146.             defaultowner = dt_defowner,
  1147.             ruleowner = dt_rulowner,
  1148.             collation = t.collation
  1149.             from dbo.systypes t, #sphelptype s
  1150.             where t.xusertype > 256 and (@typename is null or t.name = @typename)
  1151.                 and dt_xusertype = t.xusertype
  1152.             order by t.name
  1153.     end
  1154. go
  1155. /* End sp_MShelptype */
  1156.  
  1157. /*******************************************************************************/
  1158. print N''
  1159. print N'Creating sp_MSdependencies'
  1160. print N''
  1161. go
  1162.  
  1163. create procedure sp_MSdependencies
  1164. @objname nvarchar(517) = null, @objtype int = null, @flags int = 0x01fd, @objlist nvarchar(128) = null, @intrans int = null
  1165. as
  1166.     set deadlock_priority low
  1167.     
  1168.     create table #t1 (
  1169.         tid                int                NULL,
  1170.         ttype            smallint        NULL,
  1171.         tcat            smallint        NULL,
  1172.         pid                int                NULL,
  1173.         ptype            smallint        NULL,
  1174.         pcat            smallint        NULL,
  1175.         bDone            smallint        NULL
  1176.     )
  1177.     create table #t2 (
  1178.         tid                int                NULL,
  1179.         ttype            smallint        NULL,
  1180.         tcat            smallint        NULL,
  1181.         pid                int                NULL,
  1182.         ptype            smallint        NULL,
  1183.         pcat            smallint        NULL,
  1184.         bDone            smallint        NULL
  1185.     )
  1186.     create table #tempudt (
  1187.         dtype            int                NOT NULL
  1188.     )
  1189.  
  1190.     /* Worktables we'll use for optimization. */
  1191.     create table #t3 (
  1192.         tid                int                NOT NULL
  1193.     )
  1194.     create table #t4 (
  1195.         tid                int                NOT NULL
  1196.     )
  1197.     /* create clustered index #ci_t3 on #t3(tid) with allow_dup_row */
  1198.     /* create clustered index #ci_t4 on #t4(tid) with allow_dup_row */
  1199.     create clustered index #ci_t3 on #t3(tid)
  1200.     create clustered index #ci_t4 on #t4(tid)
  1201.     create table #temptrig(
  1202.         id                int                NOT NULL,
  1203.         deltrig            int                NOT NULL,
  1204.         sysstat            smallint        NOT NULL,
  1205.         category        int                NOT NULL
  1206.     )
  1207.     /* create clustered index #ci_temptrig on #temptrig (deltrig) with allow_dup_row */
  1208.     create clustered index #ci_temptrig on #temptrig (deltrig)
  1209.  
  1210.    /* 8.0 The new UDF is taking 0x0001, and we have to re-assign UDDT */
  1211.     if (@objname = N'?')
  1212.     begin
  1213.         print N'sp_MSobject_dependencies name = NULL, type = NULL, flags = 0x01fd'
  1214.         print N'  name:  name or null (all objects of type)'
  1215.         print N'  type:  type number (see below) or null'
  1216.         print N'      if both null, get all objects in database'
  1217.         print N'  flags is a bitmask of the following values:'
  1218.         print N'      0x10000  = return multiple parent/child rows per object'
  1219.         print N'      0x20000  = descending return order'
  1220.         print N'      0x40000  = return children instead of parents'
  1221.         print N'      0x80000  = Include input object in output result set'
  1222.         print N'      0x100000 = return only firstlevel (immediate) parents/children'
  1223.         print N'      0x200000 = return only DRI dependencies'
  1224.         print N'      power(2, object type number(s))  to return in results set:'
  1225.         print N'          0 (1      - 0x0001)     - UDF'
  1226.         print N'          1 (2      - 0x0002)     - system tables or MS-internal objects'
  1227.         print N'          2 (4      - 0x0004)     - view'
  1228.         print N'          3 (8      - 0x0008)     - user table'
  1229.         print N'          4 (16        - 0x0010)     - procedure'
  1230.         print N'          5 (32        - 0x0020)     - log'
  1231.         print N'          6 (64     - 0x0040)     - default'
  1232.         print N'          7 (128    - 0x0080)     - rule'
  1233.         print N'          8 (256    - 0x0100)     - trigger'
  1234.         print N'          12 (1024    - 0x0400) - uddt'
  1235.         print N'      shortcuts:'
  1236.         print N'          29     (0x011c) - trig, view, user table, procedure'
  1237.         print N'          448    (0x00c1) - rule, default, datatype'
  1238.         print N'          4606 (0x11fd) - all but systables/objects'
  1239.         print N'          4607 (0x11ff) - all'
  1240.         return 0
  1241.     end
  1242.  
  1243.     /* If this proc is called in a tight loop, it tends to fill up the log in a small tempdb too fast */
  1244.     /* for the trunc. log on chkpt thread to keep up.  So help it out here.                           */
  1245.    /* I can do this only if the current login has the proper permission to dump tempdb               */
  1246.    /* In order to find out this information, I need to switch to tempdb                              */
  1247.     declare @origdb nvarchar(128)
  1248.    declare @tempdbName nvarchar(258)
  1249.     select @origdb = db_name()
  1250.    SELECT @tempdbName = REPLACE(@origdb, N']', N']]')
  1251.  
  1252.    /* dump tran only if we are not in a transaction */
  1253.    if ( @intrans is null )
  1254.       exec (N'if (has_dbaccess(''tempdb'') = 1) begin use tempdb if (permissions() & 0x80 <> 0) dump tran tempdb with no_log use [' + @tempdbName + N'] end')
  1255.  
  1256.     /* If they want SQLDMODep_DRIOnly, remove all but usertable objects from @flags */
  1257.     if (@flags & 0x200000 <> 0)
  1258.         select @flags = (@flags & ~convert(int, 0x05ff)) | power(2, 3)
  1259.  
  1260.     if (@objtype in (12, 5, 6, 7))
  1261.     begin
  1262.         /* Print only, do not raiserror as we may be calling this blindly and this is not a real error. */
  1263.         print N'Rules, defaults, and datatypes do not have dependencies.'
  1264.         return (0)
  1265.     end
  1266.  
  1267.     /*
  1268.      * Create #t1 and #t2 as temp object holding areas.  Columns are:
  1269.      *     tid        - temp object id
  1270.      *     ttype     - temp object type
  1271.      *     pid        - parent or child object id
  1272.      *     ptype     - parent or child object type
  1273.      *     bDone     - NULL means dependencies not yet evaluated, else nonNULL.
  1274.      */
  1275.     declare @curid int, @curcat int, @rowsaffected int
  1276.     declare @allobjs int
  1277.     declare @delinputobj int
  1278.     select @allobjs = 0, @delinputobj = 0, @curid = NULL, @curcat = NULL
  1279.  
  1280.     /*
  1281.      * If both name and type are null, this means get every object in the
  1282.      * database matching the specification they passed in.  Otherwise,
  1283.      * find the passed object or all objects of the passed type.  Start off
  1284.      * loading parent info (pid, tid); these will be put into child as needed.
  1285.      * If Objlist is specified we simply load its contents into #t1.
  1286.      */
  1287.     if (@objlist is not null)
  1288.     begin
  1289.         declare @mscategory nvarchar(12)
  1290.         select @mscategory = ltrim(str(convert(int, 0x0002)))
  1291.  
  1292.         exec(N'insert #t1 (pid, ptype, pcat) select l.objid, l.objtype, o.category &' +  @mscategory +
  1293.                 N' from ' + @objlist + N' l, dbo.sysobjects o where o.id = l.objid ')
  1294.     end else begin
  1295.         if (@objname is null and @objtype is null)
  1296.         begin
  1297.             set nocount on
  1298.             select @allobjs = 1
  1299.             insert #t1 (pid, ptype, pcat) select o.id, o.sysstat & 0x0f, o.category & 0x0002 from dbo.sysobjects o
  1300.                 where ((power(2, o.sysstat & 0x0f) & 0x05ff) <> 0) and (OBJECTPROPERTY(o.id, N'IsDefaultCnst') <> 1 and OBJECTPROPERTY(o.id, N'IsRule') <> 1 )
  1301.         end else begin
  1302.             if (@objname is not null)
  1303.             begin
  1304.                 select @curid = id, @objtype = o.sysstat & 0x0f, @curcat = o.category & 0x0002 from dbo.sysobjects o where id = object_id(@objname)
  1305.                 if (@curid is null)
  1306.                 begin
  1307.                     RAISERROR (15001, -1, -1, @objname)
  1308.                     return 1
  1309.                 end
  1310.                 if (@flags & 0x80000 = 0)
  1311.                     select @delinputobj = @curid
  1312.             end
  1313.  
  1314.             set nocount on
  1315.             if (@curid is null)
  1316.                 insert #t1 (pid, ptype, pcat) select o.id, o.sysstat & 0x0f, o.category & 0x0002 from dbo.sysobjects o
  1317.                     where o.sysstat & 0x0f = @objtype
  1318.             else
  1319.                 insert #t1 (pid, ptype, pcat) values (@curid, @objtype, @curcat)
  1320.         end
  1321.     end
  1322.     /*
  1323.      * All initial objects are loaded as parents/children.  Now we loop, creating
  1324.      * rows of child/parent relationships.  Use #t2 as a temp area for the selects
  1325.      * to simulate recursion; when they find no rows, we're done with this step.
  1326.      *
  1327.      * Note that triggers are weird; they're part of a table definition but can
  1328.      * also reference other tables, so we need to evaluate them both ways.  SQL
  1329.      * Server stores the table for a trigger object as its deltrig; if a trigger
  1330.      * references another table, that relationship is stored in sysdepends.
  1331.      * This peculiarity of triggers requires separating the object-retrieval pass
  1332.      * from the creation-sequence pass (below).  Also, the fact that trigger tables
  1333.      * are stored in a non-indexed column (deltrig) requires us to use a worktable
  1334.      * if we're returning triggers, so we don't continually tablescan sysobjects.
  1335.      */
  1336.  
  1337.     if (@flags & power(2, 8) != 0)
  1338.         insert #temptrig select d.id, d.deltrig, d.sysstat, d.category from dbo.sysobjects d where OBJECTPROPERTY(d.id, N'IsTrigger') = 1
  1339.  
  1340.     while (select count(*) from #t1 where bDone is null) > 0
  1341.     begin
  1342.         /*
  1343.          * Remove Microsoft-internal or other system objects from #t1, unless
  1344.          * @flags specified including system tables.  We do this here so that
  1345.          * cascaded system dependencies are not included unless specifically
  1346.          * requested.  For other restrictions, we wait until below so that all
  1347.          * cascaded object types are fully evaluated.
  1348.          */
  1349.         if (@flags & power(2, 1) = 0)
  1350.             delete #t1 where ttype = 1 or tcat = 0x0002 or pcat = 0x0002
  1351.  
  1352.         if (@flags & 0x40000 != 0)
  1353.         begin
  1354.             if (@flags & 0x200000 = 0) begin
  1355.                 /* Table --> Triggers */
  1356.                 if (@flags & power(2, 8) != 0)
  1357.                     insert #t2 (tid, ttype, tcat, pid, ptype, pcat)
  1358.                         select distinct t.pid, t.ptype, t.pcat, o.id, o.sysstat & 0x0f, o.category & 0x0002 from #t1 t, #temptrig o
  1359.                             where t.bDone is null and t.ptype = 3 and o.deltrig = t.pid
  1360.  
  1361.                 /* Object --> sysdepends children */
  1362.                 insert #t2 (tid, ttype, tcat, pid, ptype, pcat)
  1363.                     select distinct t.pid, t.ptype, t.pcat, d.id, o.sysstat & 0x0f, o.category & 0x0002
  1364.                     from #t1 t, dbo.sysdepends d, dbo.sysobjects o
  1365.                     where t.bDone is null and d.depid = t.pid and d.id = o.id
  1366.             end
  1367.  
  1368.             /* Object --> sysreferences children (FK tables referencing this one) */
  1369.             insert #t2 (tid, ttype, tcat, pid, ptype, pcat)
  1370.                 select distinct t.pid, t.ptype, t.pcat, r.fkeyid, o.sysstat & 0x0f, o.category & 0x0002
  1371.                 from #t1 t, dbo.sysreferences r, dbo.sysobjects o
  1372.                 where t.bDone is null and r.rkeyid = t.pid and r.fkeyid = o.id
  1373.         end else begin
  1374.             if (@flags & 0x200000 = 0) begin
  1375.                 /* Trigger --> Table */
  1376.                 if (@flags & power(2, 3) != 0)
  1377.                     insert #t2 (tid, ttype, tcat, pid, ptype, pcat)
  1378.                         select distinct t.pid, t.ptype, t.pcat, o.deltrig, u.sysstat & 0x0f, u.category & 0x0002
  1379.                               from #t1 t, dbo.sysobjects o, dbo.sysobjects u
  1380.                             where t.bDone is null and t.ptype = 8 and o.id = t.pid and o.deltrig != 0 and u.id = o.deltrig
  1381.  
  1382.                 /* Object --> sysdepends parents */
  1383.                 insert #t2 (tid, ttype, tcat, pid, ptype, pcat)
  1384.                     select distinct t.pid, t.ptype, t.pcat, d.depid, o.sysstat & 0x0f, o.category & 0x0002
  1385.                     from #t1 t, dbo.sysdepends d, dbo.sysobjects o
  1386.                     where t.bDone is null and d.id = t.pid and d.depid = o.id
  1387.             end
  1388.  
  1389.             /* Object --> sysreferences parents (PK/UQ tables referenced by one) */
  1390.             insert #t2 (tid, ttype, tcat, pid, ptype, pcat)
  1391.                 select distinct t.pid, t.ptype, t.pcat, r.rkeyid, o.sysstat & 0x0f, o.category & 0x0002
  1392.                 from #t1 t, dbo.sysreferences r, dbo.sysobjects o
  1393.                 where t.bDone is null and r.fkeyid = t.pid and r.rkeyid = o.id
  1394.         end
  1395.  
  1396.         /*
  1397.          * We have this generation of parents in #t2, so clear the current
  1398.          * child generation's bDone flags.  Then insert from #t2; the current
  1399.          * parent generation becomes the next loop's child generation, with
  1400.          * bDone = null until next loop's dependencies are selected.
  1401.          */
  1402.         update #t1 set bDone = 1
  1403.         insert #t1 select * from #t2 where #t2.tid not in
  1404.             (select tid from #t1 where #t1.tid = #t2.tid and #t1.pid = #t2.pid)
  1405.         truncate table #t2
  1406.  
  1407.         /* If they only want one level, we're done.    */
  1408.         if (@flags & 0x100000 <> 0)
  1409.             update #t1 set bDone = 1
  1410.     end
  1411.  
  1412.     /*
  1413.      * The inner loop above did not put parents with no parents into the
  1414.      * child (tid) list.  Do that now, then remove all rows where tid is
  1415.      * NULL, because these were initial objects which now have a tid row.
  1416.      * Just in case, remove self-refs from #t1, and also remove rows from #t1
  1417.      * with NULL pid if a row exists for that tid where the pid is nonNULL.
  1418.      * Avoid nested self-joins by using worktables.
  1419.      */
  1420.     truncate table #t3
  1421.     insert #t3 select tid from #t1 where tid is not null
  1422.         and tid <> pid                -- make sure self-refs with no other refs go in child list
  1423.     /* update statistics #t3 #ci_t3 */
  1424.     insert #t1 (tid, ttype, tcat, bDone) select distinct pid, ptype, pcat, 0 from #t1 t
  1425.         where t.pid is not null and not exists (select * from #t3 where tid = t.pid)
  1426.     delete #t1 where tid = pid        -- now remove self-refs
  1427.  
  1428.     /*
  1429.      * Because triggers can go in both directions, we'll need to check for
  1430.      * circular dependencies on parent evaluation.  Since any tables referenced
  1431.      * by the trigger must exist before the trigger can be created, remove rows
  1432.      * where the trigger is the parent.
  1433.      */
  1434.     if (@flags & 0x40000 = 0)
  1435.         delete #t1 where ptype = 8
  1436.  
  1437.     truncate table #t3
  1438.     insert #t3 select tid from #t1 where tid is not null and pid is not null
  1439.     /* update statistics #t3 #ci_t3 */
  1440.     delete #t1 where #t1.tid is null or #t1.tid = #t1.pid
  1441.         or (#t1.pid is null and exists (select * from #t3 where tid = #t1.tid))
  1442.  
  1443.     /*
  1444.      * If we're to get all objects, get all UDDTs (which aren't in dbo.sysobjects)
  1445.      * and Rules/Defaults, assuming we're returning those types.
  1446.      */
  1447.     if (@allobjs <> 0)
  1448.     begin
  1449.         if (@flags & power(2, 12) != 0)
  1450.             insert #tempudt
  1451.                 select xusertype from dbo.systypes where xusertype > 256
  1452.         if (@flags & (power(2, 7) | power(2, 6)) != 0)
  1453.             insert #t2 (tid, ttype, tcat)
  1454.                 select id, sysstat & 0x0f, 0 from dbo.sysobjects
  1455.                 where (OBJECTPROPERTY(id, N'IsRule') = 1 or OBJECTPROPERTY(id, N'IsDefault') = 1)
  1456.                 and category & 0x0800 = 0
  1457.     end else begin
  1458.         /*
  1459.          * Not getting all objects.  Get any datatypes that
  1460.          * are referenced by objects in #t1.  We don't care about specific
  1461.          * datatype dependencies, we just want to know which ones are needed.
  1462.          */
  1463.         if (@flags & power(2, 12) != 0)
  1464.             insert #tempudt select distinct xusertype from dbo.syscolumns
  1465.                 where xusertype > 256 and id in (select tid from #t1)
  1466.  
  1467.         /*
  1468.          * Load rules and defaults needed by datatypes and other #t1 objects
  1469.          * into #t2.  Don't track specific object dependencies with these;
  1470.          * we just want to know which ones are needed.  For defaults only, eliminate
  1471.          * those which are constraints.
  1472.          */
  1473.         if (@flags & power(2, 7) != 0)
  1474.         begin
  1475.             insert #t2 (tid, ttype, tcat)
  1476.                 select distinct s.domain, 7, 0 from dbo.systypes s, #tempudt t
  1477.                     where s.domain != 0 and s.xusertype = t.dtype
  1478.                         and s.domain not in (select tid from #t1)
  1479.             insert #t2 (tid, ttype, tcat)
  1480.                 select distinct s.domain, 7, 0 from dbo.syscolumns s, #t1 t
  1481.                     where s.domain != 0 and s.id = t.tid
  1482.                         and s.domain not in (select tid from #t1)
  1483.         end
  1484.         if (@flags & power(2, 6) != 0)
  1485.         begin
  1486.             insert #t2 (tid, ttype, tcat)
  1487.                 select distinct s.tdefault, 6, 0 from dbo.systypes s, #tempudt t
  1488.                     where s.tdefault != 0 and s.xusertype = t.dtype
  1489.                         and s.tdefault not in (select tid from #t1)
  1490.                         and s.tdefault not in (select id from dbo.sysobjects where category & 0x0800 != 0)
  1491.             insert #t2 (tid, ttype, tcat)
  1492.                 select distinct s.cdefault, 6, 0 from dbo.syscolumns s, #t1 t
  1493.                     where s.cdefault != 0 and s.id = t.tid
  1494.                         and s.cdefault not in (select tid from #t1)
  1495.                         and s.cdefault not in (select id from dbo.sysobjects where category & 0x0800 != 0)
  1496.         end
  1497.     end        /* Not getting all objects */
  1498.  
  1499.     /*
  1500.      * Now that we've got all objects we want, eliminate those we don't
  1501.      * want to return.  If @inputobj and they don't want it returned,
  1502.      * remove it from the table.  Then eliminate object types they don't
  1503.      * want returned.  Make sure that in doing so we retain all parent
  1504.      * objects of the types we do want -- it is possible at this point
  1505.      * that a tid we want has no rows except those with pids we don't want.
  1506.      */
  1507.     if (@flags & 0x05ff != 0x05ff or @delinputobj != 0)
  1508.     begin
  1509.         delete #t1 where @flags & power(2, ttype) = 0 or tid = @delinputobj
  1510.  
  1511.         /*
  1512.          * Be sure that the insert does not duplicate rows that will survive the
  1513.          * following delete -- these are rows where the pid is not @delinputobj
  1514.          * and ptype is either null or a type we'll keep (if ptype is null then
  1515.          * pid hasn't been set so no need for more complex checking).
  1516.          */
  1517.         insert #t1 (tid, ttype, tcat) select distinct tid, ttype, tcat from #t1
  1518.             where (@flags & power(2, ptype) = 0 or pid = @delinputobj)
  1519.                 and tid not in (select tid from #t1 where ptype is null or
  1520.                     (pid != @delinputobj and @flags & power(2, ptype) != 0))
  1521.         delete #t1 where @flags & power(2, ptype) = 0 or pid = @delinputobj
  1522.     end
  1523.  
  1524.     /*
  1525.      * To determine creation order, find all objects which are not yet bDone
  1526.      * and have no parents or whose parents are all bDone, and set their bDone
  1527.      * to the next @curid.  This will leave bDone as the ascending order in
  1528.      * which objects must be created (topological sort).  Again, use worktables
  1529.      * to remove nested self-joins.
  1530.      */
  1531.     update #t1 set bDone = 0
  1532.     select @curid = 1, @rowsaffected = 1
  1533.     while (@rowsaffected <> 0)
  1534.     begin
  1535.         if (@flags & 0x40000 != 0) begin
  1536.             truncate table #t3
  1537.             insert #t3 select pid from #t1 where pid is not null and bDone = 0
  1538.             /* update statistics #t3 #ci_t3 */
  1539.             update #t1 set bDone = @curid where bDone = 0 and tid not in (select tid from #t3)
  1540.         end else begin
  1541.             truncate table #t3
  1542.             truncate table #t4
  1543.             insert #t3 select tid from #t1 where bDone = 0                /* Parents not yet done */
  1544.             /* update statistics #t3 #ci_t3 */
  1545.             insert #t4 select tid from #t1                                /* TIDs with (parents not yet done) */
  1546.                 where pid is not null and pid in (select tid from #t3)
  1547.             /* update statistics #t4 #ci_t4 */
  1548.             update #t1 set #t1.bDone = @curid where #t1.bDone = 0         /* TIDs who are not (TIDs with (parents not yet done)) */
  1549.                 and not exists (select * from #t4 where tid = #t1.tid)
  1550.         end
  1551.         select @rowsaffected = @@rowcount, @curid = @curid + 1
  1552.     end
  1553.  
  1554.     /* For SQL60 only, we need to check circular dependencies (DRI for tables is the only way to get them). */
  1555.     /* This will have occurred if we still have any rows in #t1 where bDone = 0, after the above loop. */
  1556.     /*
  1557.      * At this point, these are indirect (a->b->...->a), and can only be created by:
  1558.      *     create table a; create table b ref a; alter table a ref b
  1559.      * There is thus no way to create the tables in a single pass.  Further, the ALTER
  1560.      * TABLE B must be done AFTER data has been added (else the PK/FK will fail).
  1561.      * Therefore, the two-step model of
  1562.      *  - Create tables (and other objects)
  1563.      *  - Transfer data
  1564.      * does not work, so assume anyone doing this will do it in three passes (e.g. ScriptTransfer):
  1565.      *  - Create tables (and other objects) but no references (also defer some indexing, for perfomance)
  1566.      *  - Transfer data
  1567.      *  - Create references (and deferred indexing)
  1568.      * and just set bDone for everything remaining to @curid.
  1569.      */
  1570.     if exists (select * from #t1 where bDone = 0) begin
  1571.         --select "Circular Dependencies", object_name(tid) from #t1 where bDone = 0
  1572.         --RAISERROR (14300, -1, -1)
  1573.         --return 1
  1574.         update #t1 set bDone = @curid where bDone = 0
  1575.     end
  1576.  
  1577.     /*
  1578.      * Finally, return the objects.  Rules/Defaults must be created first so they're returned first,
  1579.      * followed by UDDTs. followed by all other (sysdepends/DRI) dependencies.  @curid is the bDone
  1580.      * value; we need to increment the #t1 value so our multi-result-set is in the proper sequence.
  1581.      * Of course, these never have parents, so don't return them if asking for children.
  1582.      */
  1583.     if (@flags & 0x40000 = 0) begin
  1584.         select @curid = 1
  1585.         if ((@flags & (power(2, 7) | power(2, 6)) != 0) and exists (select * from #t2)) begin
  1586.             update #t1 set bDone = bDone + 1
  1587.             select distinct oType = power(2, o.sysstat & 0x0f), oRuleDefName = o.name, oOwner = user_name(o.uid), oSequence = convert(smallint, @curid)
  1588.                 from dbo.sysobjects o, #t2 t
  1589.                 where o.id = t.tid
  1590.                 order by power(2, o.sysstat & 0x0f), o.name
  1591.             select @curid = @curid + 1
  1592.         end
  1593.         if ((@flags & power(2, 12) != 0) and exists (select * from #tempudt)) begin
  1594.             update #t1 set bDone = bDone + 1
  1595.             select distinct oType = power(2, 12), oUDDTName = c.name, oOwner = user_name(c.uid), oSequence = convert(smallint, @curid)
  1596.                 from dbo.systypes c, #tempudt t, dbo.sysobjects p
  1597.                 where c.xusertype = t.dtype
  1598.                 order by c.name
  1599.             select @curid = @curid + 1
  1600.         end
  1601.     end
  1602.  
  1603.     /*
  1604.      * Select dependency-style objects, returning parents if desired.
  1605.      * Normally sorting is in terms of who must be created first, i.e. ascending:  parent-->child-->grandchild.
  1606.      * Descending order (child-->parent-->grandparent) would be used for a graphical-dependencies evaluator showing
  1607.      * the parents.  Therefore we invert bDone if descending sort.  bDone is 1-based; min + max - bDone gives inversion.
  1608.      * Note:  Always return at least this empty set.
  1609.      */
  1610.     if (@flags & 0x20000 != 0) begin
  1611.         select @curid = max(bDone) + min(bDone) from #t1
  1612.         update #t1 set bDone = convert(smallint, @curid) - bDone
  1613.     end
  1614.     if (@flags & 0x10000 != 0)
  1615.         select distinct oType = power(2, o.sysstat & 0x0f), oObjName = o.name, oOwner = user_name(o.uid),
  1616. /*                RelType = power(2, p.sysstat & OBJTYPE_BITS), RelName = p.name, RelOwner = user_name(p.uid), */
  1617.                 RelType = case when (p.name is not null) then power(2, p.sysstat & 0x0f) else 0 end, RelName = p.name, RelOwner = user_name(p.uid),
  1618.                 oSequence = t.bDone
  1619.             from dbo.sysobjects o, dbo.sysobjects p, #t1 t
  1620.             where o.id = t.tid and p.id =* t.pid
  1621.             order by t.bDone, power(2, o.sysstat & 0x0f), o.name
  1622.     else
  1623.         select distinct oType = power(2, o.sysstat & 0x0f), oObjName = o.name, oOwner = user_name(o.uid),
  1624.                 oSequence = t.bDone
  1625.             from dbo.sysobjects o, #t1 t
  1626.             where o.id = t.tid
  1627.             order by t.bDone, power(2, o.sysstat & 0x0f), o.name
  1628.  
  1629. go
  1630. /* End sp_MSdependencies */
  1631.  
  1632. /************* DUMP THE TRANSACTION LOG **************************************/
  1633. /* Comment this out if you don't want your log dumped.  If you rerun this    */
  1634. /* script periodically, you will run out of transaction log space.           */
  1635. print N''
  1636. print N'Dumping transaction log...'
  1637. print N''
  1638. go
  1639. dump tran master with no_log
  1640. go
  1641. /************* END DUMP THE TRANSACTION LOG **********************************/
  1642.  
  1643. /*******************************************************************************/
  1644. print N''
  1645. print N'Creating sp_MStablespace'
  1646. print N''
  1647. go
  1648.  
  1649. create procedure sp_MStablespace
  1650. @name nvarchar(517), @id int = null
  1651. as
  1652.     declare @rows int, @datasizeused int, @indexsizeused int, @pagesize int
  1653.     declare @dbname nvarchar(128)
  1654.     select @dbname = db_name()
  1655.  
  1656.     if (@id is null)
  1657.         select @id = id from dbo.sysobjects where id = object_id(@name) and (OBJECTPROPERTY(id, N'IsTable') = 1)
  1658.     if (@id is null)
  1659.     begin
  1660.         RAISERROR (15009, -1, -1, @name, @dbname)
  1661.         return 1
  1662.     end
  1663.  
  1664.     /* rows */
  1665.     SELECT @rows = convert(int, rowcnt)
  1666.         FROM dbo.sysindexes
  1667.         WHERE indid < 2 and id = @id
  1668.  
  1669.     /* data */
  1670.     SELECT @datasizeused =
  1671.     (SELECT sum(dpages)
  1672.      FROM dbo.sysindexes
  1673.      WHERE indid < 2 and id = @id)
  1674.     +
  1675.     (SELECT isnull(sum(used), 0)
  1676.      FROM dbo.sysindexes
  1677.      WHERE indid = 255 and id = @id)
  1678.  
  1679.    /* Do not consider 2 < indid < 255 rows, those are nonclustered indices, and the space used by them are included by indid = 0(table) */
  1680.    /* or indid = 1(clustered index) already.  indid = 0(table) and = 1(clustered index) are mutual exclusive */
  1681.     /* index */
  1682.     SELECT @indexsizeused =
  1683.     (SELECT sum(used)
  1684.      FROM dbo.sysindexes
  1685.      WHERE indid in (0, 1, 255) and id = @id)
  1686.      - @datasizeused
  1687.  
  1688.     /* Pagesize on this server (sysindexes stores size info in pages) */
  1689.     select @pagesize = v.low / 1024 from master..spt_values v where v.number=1 and v.type=N'E'
  1690.  
  1691.     select Rows = @rows, DataSpaceUsed = @datasizeused * @pagesize, IndexSpaceUsed = @indexsizeused * @pagesize
  1692. go
  1693.  
  1694. /* End sp_MStablespace */
  1695.  
  1696. /*******************************************************************************/
  1697. print N''
  1698. print N'Creating sp_MSindexspace'
  1699. print N''
  1700. go
  1701.  
  1702. CREATE PROCEDURE sp_MSindexspace
  1703.     @tablename nvarchar(517), @index_name nvarchar(258) = NULL
  1704. AS
  1705. BEGIN
  1706.  
  1707.     CREATE TABLE #IndexSizeTemp (
  1708.         IndexID    tinyint  NOT NULL,
  1709.         IndexName  nvarchar(128) COLLATE database_default  NOT NULL,
  1710.         IndexSize  int  NOT NULL,
  1711.         Comments   nvarchar(28)  COLLATE database_default NOT NULL
  1712.     )
  1713.  
  1714.   DECLARE @table_id int
  1715.   DECLARE @index_id int
  1716.   DECLARE @msg nvarchar(2000)
  1717.   DECLARE @pagesize int
  1718.   select @pagesize = v.low / 1024 from master..spt_values v where v.number=1 and v.type=N'E'
  1719.  
  1720.   /* Make sure @tablename is local to the current database */
  1721.  
  1722.   /* Make sure that @tablename and @index_name exist, we are checking table instead of UserTable */
  1723.   SELECT @table_id = id
  1724.   FROM dbo.sysobjects
  1725.   WHERE (id = object_id(@tablename))
  1726.     AND ((OBJECTPROPERTY(id, N'IsTable') = 1) OR (OBJECTPROPERTY(id, N'IsView') = 1))
  1727.   IF (@table_id is NULL)
  1728.   BEGIN
  1729.     RAISERROR (15001, -1, -1, @tablename)
  1730.     RETURN(1)
  1731.   END
  1732.   IF (@index_name is not NULL)
  1733.   BEGIN
  1734.     SELECT @index_id = indid
  1735.     FROM dbo.sysindexes
  1736.     WHERE (name = @index_name)
  1737.       AND (id = object_id(@tablename))
  1738.     IF (@index_id is NULL)
  1739.     BEGIN
  1740.       SELECT @msg = @tablename + N'.' + @index_name
  1741.       RAISERROR (15001, -1, -1, @msg)
  1742.       RETURN(1)
  1743.     END
  1744.   END
  1745.   /* Ok, we're good to go */
  1746.   IF (user_id() = 1)
  1747.     CHECKPOINT
  1748.   IF (@index_name is NULL)
  1749.   BEGIN
  1750.     INSERT INTO #IndexSizeTemp
  1751.     SELECT indid, name, 0, N''
  1752.     FROM dbo.sysindexes
  1753.     WHERE (id = object_id(@tablename))
  1754.       AND ((indid > 0) AND (indid < 255))
  1755.     UPDATE #IndexSizeTemp
  1756.     SET IndexSize = used * @pagesize,
  1757.         Comments = N'(None)'
  1758.     FROM dbo.sysindexes si, #IndexSizeTemp ist
  1759.     WHERE (id = object_id(@tablename))
  1760.       AND (indid > 1) AND (indid < 255)
  1761.       AND (si.indid = ist.IndexID)
  1762.     UPDATE #IndexSizeTemp
  1763.     SET IndexSize = (used - dpages - isnull((SELECT sum(used)
  1764.                                              FROM dbo.sysindexes
  1765.                                              WHERE (indid > 1) AND (indid < 255)
  1766.                                                AND (id = object_id(@tablename))), 0)) * @pagesize,
  1767.         Comments = N'Size excludes actual data.'
  1768.     FROM dbo.sysindexes si, #IndexSizeTemp ist
  1769.     WHERE (id = object_id(@tablename))
  1770.       AND (indid = 1)
  1771.       AND (si.indid = ist.IndexID)
  1772.     SELECT N'Index ID' = IndexID, N'Index Name' = IndexName, N'Size (KB)' = IndexSize, Comments
  1773.     FROM #IndexSizeTemp
  1774.     ORDER BY IndexID
  1775.     DROP TABLE #IndexSizeTemp
  1776.   END
  1777.   ELSE
  1778.   BEGIN
  1779.     DECLARE @indid int
  1780.     SELECT @indid = indid
  1781.     FROM dbo.sysindexes
  1782.     WHERE (id = object_id(@tablename))
  1783.       AND (name = @index_name)
  1784.     /* The non-clustered index case */
  1785.     IF ((@indid > 1) AND (@indid < 255))
  1786.     BEGIN
  1787.       SELECT N'Size (KB)' = used * @pagesize
  1788.       FROM dbo.sysindexes
  1789.       WHERE (id = object_id(@tablename))
  1790.         AND (name = @index_name)
  1791.       RETURN(0)
  1792.     END
  1793.     /* The clustered index case */
  1794.     IF (@indid = 1)
  1795.     BEGIN
  1796.       SELECT N'Size (KB)' =
  1797.              (used - dpages - isnull((SELECT sum(used)
  1798.                                       FROM dbo.sysindexes
  1799.                                       WHERE (indid > 1) AND (indid < 255)
  1800.                                         AND (id = object_id(@tablename))
  1801.                                         AND (name = @index_name)), 0)) * @pagesize
  1802.       FROM dbo.sysindexes
  1803.       WHERE (id = object_id(@tablename))
  1804.         AND (name = @index_name)
  1805.     END
  1806.   END
  1807.   RETURN(0)
  1808. END
  1809. go
  1810. /* End sp_MSindexspace */
  1811.  
  1812. /*-----------------------------------------------------*/
  1813. /*-----------------------------------------------------*/
  1814. print N''
  1815. print N'Creating sp_MStablerefs'
  1816. print N''
  1817. go
  1818.  
  1819. create procedure sp_MStablerefs
  1820.     @tablename nvarchar(517),                    
  1821.     @type nvarchar(20) = N'actualtables',        
  1822.     @direction nvarchar(20) = N'primary',        
  1823.     @reftable nvarchar(517) = null,            
  1824.    @flags int = 0
  1825. as
  1826.    /* tablename: table whose references are being evaluated */
  1827.    /* type     : '[actual | all][tables | keys | keycols]'; all candidates, or only those actually referenced */
  1828.    /* direction: look for references from @tablename to 'primary' table(s), or to @tablename from 'foreign' table(s) */
  1829.    /* reftable : limit scope to this table, if non-null */
  1830.    /*** @flags added for DaVinci uses.  If the bit isn't set, use 6.5 ***/
  1831.    /*** sp_MStablerefs '%s', null, 'both'                             ***/
  1832.  
  1833.     create table #sprefs (
  1834.         id                    int                NOT NULL,     /* id of reftable */
  1835.         constid                int                NULL,         /* id of key */
  1836.         referenced            bit                NOT NULL    /* well, is it? */
  1837.     )
  1838.  
  1839.     /* @flags is for daVinci */
  1840.     if (@flags is null)
  1841.         select @flags = 0
  1842.  
  1843.     if (@tablename = N'?') begin
  1844.         PRINT N''
  1845.         PRINT N'sp_MStablerefs:'
  1846.         PRINT N'@tablename nvarchar(257),                    /* table whose references are being evaluated */'
  1847.         PRINT N'@type nvarchar(20) = [actualtables],        /* [[actual | all][tables | keys | keycols]]; all candidates, or only those actually referenced */'
  1848.         PRINT N'@direction nvarchar(20) = [primary],        /* look for references from @tablename to [primary] or to @tablename from [foreign], or [both] */'
  1849.         PRINT N'@reftable nvarchar(257) = null                /* limit scope to this table, if non-null */'
  1850.         return 0
  1851.     end
  1852.  
  1853.     if (lower(@direction) = N'both') begin
  1854.         select
  1855.          N'PK_Table' = PKT.name,
  1856.          N'FK_Table' = FKT.name,
  1857.          N'Constraint' = object_name(r.constid),
  1858.             c.status,
  1859.             cKeyCol1 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey1)),
  1860.             cKeyCol2 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey2)),
  1861.             cKeyCol3 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey3)),
  1862.             cKeyCol4 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey4)),
  1863.             cKeyCol5 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey5)),
  1864.             cKeyCol6 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey6)),
  1865.             cKeyCol7 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey7)),
  1866.             cKeyCol8 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey8)),
  1867.             cKeyCol9 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey9)),
  1868.             cKeyCol10 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey10)),
  1869.             cKeyCol11 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey11)),
  1870.             cKeyCol12 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey12)),
  1871.             cKeyCol13 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey13)),
  1872.             cKeyCol14 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey14)),
  1873.             cKeyCol15 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey15)),
  1874.             cKeyCol16 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey16)),
  1875.             cRefCol1 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey1)),
  1876.             cRefCol2 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey2)),    
  1877.             cRefCol3 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey3)),
  1878.             cRefCol4 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey4)),
  1879.             cRefCol5 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey5)),
  1880.             cRefCol6 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey6)),
  1881.             cRefCol7 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey7)),
  1882.             cRefCol8 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey8)),
  1883.             cRefCol9 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey9)),
  1884.             cRefCol10 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey10)),
  1885.             cRefCol11 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey11)),
  1886.             cRefCol12 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey12)),
  1887.             cRefCol13 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey13)),
  1888.             cRefCol14 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey14)),
  1889.             cRefCol15 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey15)),
  1890.             cRefCol16 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey16)),
  1891.             N'PK_Table_Owner' = user_name(PKT.uid),
  1892.             N'FK_Table_Owner' = user_name(FKT.uid),
  1893.          N'DeleteCascade' = OBJECTPROPERTY( r.constid, N'CnstIsDeleteCascade'),
  1894.          N'UpdateCascade' = OBJECTPROPERTY( r.constid, N'CnstIsUpdateCascade')
  1895.       from dbo.sysreferences r, dbo.sysconstraints c, dbo.sysobjects PKT, dbo.sysobjects FKT
  1896.       where r.constid = c.constid and (@tablename is null or
  1897.          (r.rkeyid = object_id(@tablename) or r.fkeyid = object_id(@tablename)))
  1898.       and PKT.id = r.rkeyid and FKT.id = r.fkeyid
  1899.       return 0
  1900.     end /* @direction = 'both' */
  1901.  
  1902.     declare @id int, @refid int
  1903.     select @id = object_id(@tablename), @refid = object_id(@reftable)
  1904.     if (@tablename is not null and @id is null) begin
  1905.         RAISERROR (15001, -1, -1, @tablename)
  1906.         return 1
  1907.     end
  1908.     if (@reftable is not null and @refid is null) begin
  1909.         RAISERROR (15001, -1, -1, @reftable)
  1910.         return 1
  1911.     end
  1912.  
  1913.     declare @dotables bit, @doall bit, @doprimary bit, @docols bit
  1914.     select     @dotables = case when (@type like N'allt%' or @type like N'actualt%') then 1 else 0 end,
  1915.             @doall = case when (@type like N'all%') then 1 else 0 end,
  1916.             @doprimary = case when (@direction like N'p%') then 1 else 0 end,
  1917.             @docols = case when (@type like N'%keycol%') then 1 else 0 end
  1918.  
  1919.     /* If a specific @tablename specified, see if it has the kind of keys we want. */
  1920.     /* If asking for references from @tablename to 'primary', we must have an FKEY; */
  1921.     /* if asking for references to @tablename from 'foreign', we must have an active REFerence. */
  1922.     if (@id is not null) begin
  1923.         declare @wantkeytype int
  1924.         select @wantkeytype = case @doprimary when 1 then 0x4 else 0x8 end
  1925.         if not exists (select * from dbo.sysobjects where id = @id and category & @wantkeytype <> 0)
  1926.             goto ReturnSet
  1927.     end
  1928.  
  1929.     if (@dotables = 1) begin
  1930.         if (@doprimary = 1) begin
  1931.             /* Get all candidate tables (those with Primary/Unique keys in sysconstraints). */
  1932.             insert #sprefs
  1933.                 select distinct id, null, 0 from dbo.sysconstraints where status & 0x0f in (1, 2)
  1934.  
  1935.             /* Update the referenced bit if this table references it. */
  1936.             update #sprefs set referenced = 1
  1937.                 where id in (select rkeyid from dbo.sysreferences where fkeyid = @id)
  1938.         end else begin
  1939.             /* All user tables are foreign-key candidate tables. */
  1940.             insert #sprefs
  1941.                 select distinct id, null, 0 from dbo.sysobjects where OBJECTPROPERTY(id, N'IsUserTable') = 1
  1942.  
  1943.             /* Update the referenced bit if it references this table. */
  1944.             update #sprefs set referenced = 1
  1945.                 where id in (select fkeyid from dbo.sysreferences where rkeyid = @id)
  1946.         end    /* direction */
  1947.  
  1948.     end else begin    /* keys */
  1949.         if (@doprimary = 1) begin
  1950.             /* Get all candidate tables (those with Primary/Unique keys in sysconstraints) and the keys. */
  1951.             insert #sprefs
  1952.                 select distinct id, constid, 0 from dbo.sysconstraints where status & 0x0f in (1, 2)
  1953.  
  1954.             /* Follow r.rkeyindid back to sysindexes to get the name and then 'rconstid' to see if this table references it. */
  1955.          update #sprefs set referenced = 1 from #sprefs s, dbo.sysreferences r, dbo.sysindexes i
  1956.             where r.fkeyid = @id
  1957.             and i.id = r.rkeyid and i.indid = r.rkeyindid and i.status & 0x1800 <> 0
  1958.             and s.constid = object_id(N'[' + REPLACE(i.name, N']', N']]') + N']')
  1959.  
  1960.         end else begin
  1961.             /* First add tables with FOREIGN keys defined. */
  1962.             insert #sprefs
  1963.                 select distinct id, constid, 0 from dbo.sysconstraints where status & 0x0f in (3)
  1964.  
  1965.             /* All user tables are foreign-key candidate tables, so add any tables we haven't yet, if @doall. */
  1966.             /* (This would be used for 'push' key definition; defining FK's from the standpoint of the PK table). */
  1967.             insert #sprefs
  1968.                 select distinct id, null, 0 from dbo.sysobjects where OBJECTPROPERTY(id, N'IsUserTable') = 1
  1969.                     and @doall = 1 and id not in (select id from #sprefs)
  1970.  
  1971.             /* Update the referenced bit if it references this table. */
  1972.             update #sprefs set referenced = 1
  1973.                 where constid in (select constid from dbo.sysreferences where rkeyid = @id)
  1974.         end    /* direction */
  1975.     end    /* tables or keys */
  1976.     
  1977.     /* Exclude system and MS-internal objects, or tables/keys that aren't in the @reftable we want, if any specified. */
  1978.     delete #sprefs where id in (select id from dbo.sysobjects where OBJECTPROPERTY(id, N'IsUserTable') <> 1 or category & 0x0002 <> 0)
  1979.             or (@refid is not null and id != @refid)
  1980.  
  1981.     /* Output */
  1982. ReturnSet:
  1983.     if (@docols = 0) begin
  1984.         if (@tablename is not null) begin
  1985.             select candidate_table = N'[' + REPLACE(user_name(o.uid), N']', N']]') + N']' + N'.' + N'[' + REPLACE(object_name(o.id), N']', N']]') + N']',
  1986.                candidate_key = case @dotables when 1 then N'N/A' else object_name(s.constid) end, s.referenced
  1987.                from #sprefs s, dbo.sysobjects o where o.id = s.id and (@doall = 1 or s.referenced = 1)
  1988.                order by object_name(o.id), user_name(o.uid), object_name(s.constid)
  1989.       end else begin
  1990.             select candidate_table = N'[' + REPLACE(user_name(o.uid), N']', N']]') + N']' + N'.' + N'[' + REPLACE(object_name(o.id), N']', N']]') + N']',
  1991.                candidate_key = case @dotables when 1 then N'N/A' else object_name(s.constid) end
  1992.                from #sprefs s, dbo.sysobjects o where o.id = s.id
  1993.                order by object_name(o.id), user_name(o.uid), object_name(s.constid)
  1994.       end
  1995.     end else begin    /* @docols = 1 */
  1996.         /* This is currently just implemented for 'nonNULLtablename', 'actualkeycols', 'foreign'. */
  1997.          select candidate_table = N'[' + REPLACE(user_name(o.uid), N']', N']]') + N']' + N'.' + N'[' + REPLACE(object_name(o.id), N']', N']]') + N']',
  1998.                candidate_key = object_name(s.constid),
  1999.                cKeyCol1 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey1)),
  2000.                cKeyCol2 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey2)),
  2001.                cKeyCol3 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey3)),
  2002.                cKeyCol4 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey4)),
  2003.                cKeyCol5 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey5)),
  2004.                cKeyCol6 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey6)),
  2005.                cKeyCol7 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey7)),
  2006.                cKeyCol8 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey8)),
  2007.                cKeyCol9 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey9)),
  2008.                cKeyCol10 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey10)),
  2009.                cKeyCol11 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey11)),
  2010.                cKeyCol12 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey12)),
  2011.                cKeyCol13 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey13)),
  2012.                cKeyCol14 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey14)),
  2013.                cKeyCol15 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey15)),
  2014.                cKeyCol16 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey16))
  2015.             from #sprefs s, dbo.sysobjects o, dbo.sysreferences r
  2016.             where o.id = s.id and r.constid = s.constid and s.referenced = 1
  2017.             order by object_name(o.id), user_name(o.uid), object_name(s.constid)
  2018.     end
  2019. go
  2020. /* End sp_MStablerefs */
  2021.  
  2022.  
  2023. /*******************************************************************************/
  2024. print N''
  2025. print N'Creating sp_MStablekeys'
  2026. print N''
  2027. go
  2028.  
  2029. create procedure sp_MStablekeys
  2030. @tablename nvarchar(776) = null, @colname nvarchar(258) = null, @type int = null, @keyname nvarchar(517) = null, @flags int = null
  2031. as
  2032.  
  2033.  
  2034.  
  2035.     create table #tempID
  2036.        (
  2037.       cName nvarchar(132) COLLATE database_default NOT NULL,      /* Index name */
  2038.       cPK1  int, cPK2  int, cPK3  int, cPK4  int, cPK5  int, cPK6  int, cPK7  int, cPK8  int,
  2039.       cPK9  int, cPK10 int, cPK11 int, cPK12 int, cPK13 int, cPK14 int, cPK15 int, cPK16 int    /* 1 if DESC  */
  2040.       )
  2041.  
  2042.    create table #tempID2
  2043.       (
  2044.       cPKName  nvarchar(132) COLLATE database_default NOT NULL,      /* PK name */
  2045.       cPK      int                                   /* Combined info for PK */
  2046.       )
  2047.  
  2048.     create table #spkeys
  2049.     (
  2050.         cType          tinyint NOT NULL, /* key Type */
  2051.         cName          nvarchar(258) COLLATE database_default NOT NULL, /* key Name */
  2052.         cFlags         int  NULL,  /* e.g., 1 = clustered for PK/Unique */
  2053.         cColCount      int  NULL,  /* number of columns (or column pairs) in the key */
  2054.         cFillFactor    tinyint NULL, /* Fill factor of index creation */
  2055.         cRefTable      nvarchar(520) COLLATE database_default NULL,        /* owner-qual Referenced table name for FKs */
  2056.         cRefKey        nvarchar(260)  COLLATE database_default NULL,        /* name of referenced key in referenced table */
  2057.             -- Note:  cConstID replaces the column list used in 6.0, for speed.
  2058.             -- The output set MUST replace this with either index_col(@tablename, cIndexID, 1-16) and NULL * 16
  2059.             -- (for PK/UQ) UNION col_name(r.fkeyid, r.fkey1-16) and col_name(r.rkeyid, r.rkey1-16), for SQLDMO,
  2060.             -- and these MUST BE nvarchar(132) for alignment in the SQLDMO cache structure!
  2061.         cConstID       int  NULL, /* Reference constraint ID, if Foreign Key  */
  2062.         cIndexID       int  NULL, /* ID of this key's index, if PK/UQ */
  2063.         cGroupName     sysname COLLATE database_default  NULL,  /* FileGroup name of this key, if PK/UQ */
  2064.         cDisabled      int  NULL,  /* 0 if enabled, 1 if disabled */
  2065.         cPrimaryFG     int  NULL,  /* 1 if primary FG, 0 otherwise */
  2066.       cDeleteCascade int  NULL,    /* 1 if it is a foreign key constraint with a cascade delete */
  2067.       cUpdateCascade int  NULL     /* 1 if it is a foreign key constraint with a cascade update */
  2068.     )
  2069.  
  2070.     /* This proc returns the table's DRI keys.  @type is the type(s) of key(s) to return. */
  2071.     /* Make sure @type is only the key types (DRI_PRIMARYKEY, DRI_UNIQUE, DRI_REFERENCE). */
  2072.     if (@type is null)
  2073.         select @type = 0x000e
  2074.     else
  2075.         select @type = @type & 0x000e
  2076.  
  2077.     /* Flags usage:  For daVinci, to pass call thru to sp_MStablerefs. */
  2078.     if (@flags is null)
  2079.         select @flags = 0
  2080.  
  2081.     set nocount on
  2082.     declare @cType int, @cName nvarchar(258), @cFlags int, @cRefTable nvarchar(520), @fillfactor tinyint
  2083.     declare @objid int, @constid int, @indid int, @keycnt int, @q1 nvarchar(2000), @q2 nvarchar(2000), @objtype int, @groupname sysname
  2084.     declare @haskeytypes int, @wantkeytypes int
  2085.    declare @cDisabled int, @PrimaryFG int, @cDeleteCascade int, @cUpdateCascade int
  2086.  
  2087.     /* First see if @keyname was defined, and override @tablename and @type if so. */
  2088.     if (@keyname is not null)
  2089.     begin
  2090.          select @objid = id, @type = power(2, status & 0x0f) from dbo.sysconstraints where constid = object_id(@keyname)
  2091.          if (@objid is null)    begin
  2092.             RAISERROR (15001, -1, -1, @keyname)
  2093.             return 1
  2094.          end
  2095.          /* Now get the tablename for the index_col below */
  2096.          select @tablename = N'[' + REPLACE(user_name(uid), N']', N']]') + N']' + N'.' + N'[' + REPLACE(name, N']', N']]') + N']' from dbo.sysobjects where id = @objid
  2097.     end else begin
  2098.         /* Want all keys for this table (of @type type). */
  2099.         select @objid = id, @objtype = (case when OBJECTPROPERTY(id, N'IsTable') = 1 then 1 else 0 end), @haskeytypes = category & 0x0604
  2100.             from dbo.sysobjects where id = object_id(@tablename)
  2101.         if (@objid is null)    begin
  2102.             RAISERROR (15001, -1, -1, @tablename)
  2103.             return 1
  2104.         end
  2105.         if (@objtype <> 1)    begin
  2106.             RAISERROR (15218, -1, -1, @tablename)
  2107.             return 1
  2108.         end
  2109.         if @colname is not null and not exists (select * from dbo.syscolumns where id = @objid and name = @colname) begin
  2110.             RAISERROR (15253, -1, -1, @colname, @tablename)
  2111.             return 1
  2112.         end
  2113.  
  2114.         /* Skip cursor opening if we don't have any keys (of the type wanted); return a set anyway, for the cache. */
  2115.         if (@haskeytypes = 0)
  2116.             goto ReturnSet
  2117.  
  2118.         /* Map from the input bitmask to the category bitmask */
  2119.         select @wantkeytypes = 0
  2120.         if ((@type & power(2, 1)) <> 0)
  2121.             select @wantkeytypes = @wantkeytypes | 0x200
  2122.         if ((@type & power(2, 2)) <> 0)
  2123.             select @wantkeytypes = @wantkeytypes | 0x400
  2124.         if ((@type & power(2, 3)) <> 0)
  2125.             select @wantkeytypes = @wantkeytypes | 0x4
  2126.         if ((@haskeytypes & @wantkeytypes) = 0)
  2127.             goto ReturnSet
  2128.     end
  2129.  
  2130.     /* Preprocessor won't replace within quotes so have to use str(). */
  2131.     declare @sysgenname nvarchar(12), @pkstr nvarchar(12), @uqstr nvarchar(12), @fkstr nvarchar(12), @objtypebits nvarchar(12)
  2132.     select @sysgenname = ltrim(str(convert(int, 0x00020000)))
  2133.     select @pkstr = ltrim(str(convert(int, 1)))
  2134.     select @uqstr = ltrim(str(convert(int, 2)))
  2135.     select @fkstr = ltrim(str(convert(int, 3)))
  2136.     select @objtypebits = ltrim(str(convert(int, 0x0f)))
  2137.  
  2138.     /* Other ints we need strings for */
  2139.     declare @objidstr nvarchar(12), @typestr nvarchar(12)
  2140.     select @objidstr = ltrim(str(@objid))
  2141.     select @typestr = ltrim(str(@type))
  2142.  
  2143.     /* Qualifying key name. */
  2144.     declare @qualkeyname nvarchar(100)
  2145.     select @qualkeyname = null
  2146.     if (@keyname is not null) begin
  2147.       select @qualkeyname = N' and constid = object_id(''' + @keyname + N''')'
  2148.    end
  2149.  
  2150.     /*********************/
  2151.     /* Main cursor loop. */
  2152.     /*********************/
  2153. /*    exec(N'declare hC insensitive cursor for select constid, status & ' + @objtypebits + N', status & ' + @sysgenname + */
  2154.     exec(N'declare hC cursor global for select constid, status & ' + @objtypebits + N', status & ' + @sysgenname +
  2155.             N' from dbo.sysconstraints where id = ' + @objidstr + N' and (' + @typestr + N' & power(2, status & 0x0f) != 0) ' + @qualkeyname)
  2156.     open hC
  2157.     fetch hC into @constid, @cType, @cFlags
  2158.     while (@@fetch_status >= 0) begin
  2159.         if (object_name(@constid) is null) begin
  2160.             raiserror 55555 N'Assert failed:  object_name(@constid) is null in sp_MStablekeys (pk/uq)'
  2161.             return 1
  2162.         end
  2163.  
  2164.         /* DRI_PRIMARYKEY, DRI_UNIQUE */
  2165.         if (@cType in (1, 2)) begin
  2166.             /* Get the index id enforcing this constraint. */
  2167.             select @indid = i.indid, @cName = o.name, @fillfactor = i.OrigFillFactor,
  2168.                     @cFlags = @cFlags | (case indid when 1 then 0x00000001 else 0 end),        /* test for clustered index */
  2169.                /* clustered index keys are part of non-clustered index key list, which cause incorrect sysindexes.keycnt */
  2170.                     @keycnt = case indid when 1 then keycnt else (select count(x.id) from dbo.sysindexkeys x where i.indid = x.indid and x.id = @objid) end,
  2171.                @groupname = f.groupname,
  2172.                @PrimaryFG = FILEGROUPPROPERTY( f.groupname, N'IsPrimaryFG' )
  2173.                 from dbo.sysindexes i, dbo.sysobjects o, dbo.sysfilegroups f
  2174.             /* Use '=' instead of 'LIKE' in comparision, so we can handle wide card character correctly */
  2175.                 where o.id = @constid and i.name = o.name and i.status & 0x1800 <> 0 and i.groupid = f.groupid
  2176.             if (@indid is null) begin
  2177.                 raiserror 77777 N'Assert failed:  @indid is null in sp_MStablekeys (pk/uq)'
  2178.                 return 1
  2179.             end
  2180.  
  2181.             insert #spkeys values (@cType, @cName, @cFlags, @keycnt, @fillfactor, null, null, null, @indid, @groupname, 0, @PrimaryFG, 0, 0)
  2182.         end
  2183.  
  2184.         /* DRI_REFERENCE */
  2185.         else if (@cType in (3)) begin
  2186.             /* Get the key column information from sysreferences. */
  2187.          select @keycnt = r.keycnt, @cName = object_name(r.constid), @cRefTable = N'[' + user_name(o.uid) + N']' + N'.' + N'[' + o.name + N']',
  2188.                @cDisabled = OBJECTPROPERTY( r.constid, N'CnstIsDisabled' ),
  2189.                @cDeleteCascade = OBJECTPROPERTY( r.constid, N'CnstIsDeleteCascade'),
  2190.                @cUpdateCascade = OBJECTPROPERTY( r.constid, N'CnstIsUpdateCascade')
  2191.             from dbo.sysreferences r, dbo.sysobjects o where r.constid = @constid and o.id = r.rkeyid
  2192.  
  2193.             /* Follow r.rkeyindid back to sysindexes to get the ref key name. */
  2194.             declare @cRefKey nvarchar(132)
  2195.             select @cRefKey = i.name, @cFlags = c.status from dbo.sysreferences r, dbo.sysindexes i, dbo.sysconstraints c
  2196.                 where c.constid = r.constid and r.constid = @constid
  2197.                 and i.id = r.rkeyid and i.indid = r.rkeyindid and i.status & 0x1800 <> 0
  2198.  
  2199.             /* Load our temp table. */
  2200.             insert #spkeys values (@cType, @cName, @cFlags, @keycnt, null, @cRefTable, @cRefKey, @constid, null, null, @cDisabled, 0, @cDeleteCascade, @cUpdateCascade)
  2201.         end        /* Key type */
  2202.  
  2203.         /* Get the next row. */
  2204.         fetch hC into @constid, @cType, @cFlags
  2205.     end            /* PRIMARY/UNIQUE */
  2206.     deallocate hC
  2207.  
  2208.    /* Work on the descending information */
  2209.    set nocount on
  2210.    insert #tempID
  2211.       select cName,
  2212.       indexkey_property(object_id(@tablename), cIndexID, 1, N'isdescending'),
  2213.       indexkey_property(object_id(@tablename), cIndexID, 2, N'isdescending'),
  2214.       indexkey_property(object_id(@tablename), cIndexID, 3, N'isdescending'),
  2215.       indexkey_property(object_id(@tablename), cIndexID, 4, N'isdescending'),
  2216.       indexkey_property(object_id(@tablename), cIndexID, 5, N'isdescending'),
  2217.       indexkey_property(object_id(@tablename), cIndexID, 6, N'isdescending'),
  2218.       indexkey_property(object_id(@tablename), cIndexID, 7, N'isdescending'),
  2219.       indexkey_property(object_id(@tablename), cIndexID, 8, N'isdescending'),
  2220.       indexkey_property(object_id(@tablename), cIndexID, 9, N'isdescending'),
  2221.       indexkey_property(object_id(@tablename), cIndexID, 10, N'isdescending'),
  2222.       indexkey_property(object_id(@tablename), cIndexID, 11, N'isdescending'),
  2223.       indexkey_property(object_id(@tablename), cIndexID, 12, N'isdescending'),
  2224.       indexkey_property(object_id(@tablename), cIndexID, 13, N'isdescending'),
  2225.       indexkey_property(object_id(@tablename), cIndexID, 14, N'isdescending'),
  2226.       indexkey_property(object_id(@tablename), cIndexID, 15, N'isdescending'),
  2227.       indexkey_property(object_id(@tablename), cIndexID, 16, N'isdescending')
  2228.       from #spkeys
  2229.         order by cType, cName
  2230.  
  2231.    /* Construct the bit */
  2232.    declare @idx int
  2233.    declare @Name nvarchar(132)
  2234.    declare @Inx_1 int, @Inx_2 int, @Inx_3 int, @Inx_4 int, @Inx_5 int, @Inx_6 int, @Inx_7 int, @Inx_8 int
  2235.    declare @Inx_9 int, @Inx_10 int, @Inx_11 int, @Inx_12 int, @Inx_13 int, @Inx_14 int, @Inx_15 int, @Inx_16 int
  2236.  
  2237.    declare hCur cursor global for select * from #tempID
  2238.    open hCur
  2239.    fetch next from hCur into @Name, @Inx_1, @Inx_2, @Inx_3, @Inx_4, @Inx_5, @Inx_6, @Inx_7, @Inx_8,
  2240.                              @Inx_9, @Inx_10, @Inx_11, @Inx_12, @Inx_13, @Inx_14, @Inx_15, @Inx_16
  2241.    while (@@FETCH_STATUS = 0)
  2242.       begin
  2243.       select @idx = 0x0000
  2244.       select @idx = (case when (@Inx_1 = 1) then @idx | 0x0001 else @idx end), @idx = (case when (@Inx_2 = 1) then @idx | 0x0002 else @idx end), @idx = (case when (@Inx_3 = 1) then @idx | 0x0004 else @idx end), @idx = (case when (@Inx_4 = 1) then @idx | 0x0008 else @idx end), @idx = (case when (@Inx_5 = 1) then @idx | 0x0010 else @idx end), @idx = (case when (@Inx_6 = 1) then @idx | 0x0020 else @idx end), @idx = (case when (@Inx_7 = 1) then @idx | 0x0040 else @idx end), @idx = (case when (@Inx_8 = 1) then @idx | 0x0080 else @idx end),
  2245.              @idx = (case when (@Inx_9 = 1) then @idx | 0x0100 else @idx end), @idx = (case when (@Inx_10 = 1) then @idx | 0x0200 else @idx end), @idx = (case when (@Inx_11 = 1) then @idx | 0x0400 else @idx end), @idx = (case when (@Inx_12 = 1) then @idx | 0x0800 else @idx end), @idx = (case when (@Inx_13 = 1) then @idx | 0x1000 else @idx end), @idx = (case when (@Inx_14 = 1) then @idx | 0x2000 else @idx end), @idx = (case when (@Inx_15 = 1) then @idx | 0x4000 else @idx end), @idx = (case when (@Inx_16 = 1) then @idx | 0x8000 else @idx end)
  2246.       insert #tempID2 select @Name, @idx
  2247.  
  2248.       fetch next from hCur into @Name, @Inx_1, @Inx_2, @Inx_3, @Inx_4, @Inx_5, @Inx_6, @Inx_7, @Inx_8,
  2249.                                 @Inx_9, @Inx_10, @Inx_11, @Inx_12, @Inx_13, @Inx_14, @Inx_15, @Inx_16
  2250.       end
  2251.    close hCur
  2252.    deallocate hCur
  2253.    set nocount off
  2254.  
  2255.  
  2256.     /* Now output the data */
  2257. ReturnSet:
  2258.     set nocount off
  2259.     select cType, cName, cFlags, cColCount, cFillFactor, cRefTable, cRefKey,
  2260.             cKeyCol1 = convert(nvarchar(132), index_col(@tablename, cIndexID, 1)),
  2261.             cKeyCol2 = convert(nvarchar(132), index_col(@tablename, cIndexID, 2)),    
  2262.             cKeyCol3 = convert(nvarchar(132), index_col(@tablename, cIndexID, 3)),
  2263.             cKeyCol4 = convert(nvarchar(132), index_col(@tablename, cIndexID, 4)),
  2264.             cKeyCol5 = convert(nvarchar(132), index_col(@tablename, cIndexID, 5)),
  2265.             cKeyCol6 = convert(nvarchar(132), index_col(@tablename, cIndexID, 6)),    
  2266.             cKeyCol7 = convert(nvarchar(132), index_col(@tablename, cIndexID, 7)),
  2267.             cKeyCol8 = convert(nvarchar(132), index_col(@tablename, cIndexID, 8)),
  2268.             cKeyCol9 = convert(nvarchar(132), index_col(@tablename, cIndexID, 9)),
  2269.             cKeyCol10 = convert(nvarchar(132), index_col(@tablename, cIndexID, 10)),
  2270.             cKeyCol11 = convert(nvarchar(132), index_col(@tablename, cIndexID, 11)),
  2271.             cKeyCol12 = convert(nvarchar(132), index_col(@tablename, cIndexID, 12)),
  2272.             cKeyCol13 = convert(nvarchar(132), index_col(@tablename, cIndexID, 13)),
  2273.             cKeyCol14 = convert(nvarchar(132), index_col(@tablename, cIndexID, 14)),    
  2274.             cKeyCol15 = convert(nvarchar(132), index_col(@tablename, cIndexID, 15)),
  2275.             cKeyCol16 = convert(nvarchar(132), index_col(@tablename, cIndexID, 16)),
  2276.             cRefCol1 = convert(nvarchar(132), null),
  2277.             cRefCol2 = convert(nvarchar(132), null),
  2278.             cRefCol3 = convert(nvarchar(132), null),
  2279.             cRefCol4 = convert(nvarchar(132), null),
  2280.             cRefCol5 = convert(nvarchar(132), null),
  2281.             cRefCol6 = convert(nvarchar(132), null),
  2282.             cRefCol7 = convert(nvarchar(132), null),
  2283.             cRefCol8 = convert(nvarchar(132), null),
  2284.             cRefCol9 = convert(nvarchar(132), null),
  2285.             cRefCol10 = convert(nvarchar(132), null),
  2286.             cRefCol11 = convert(nvarchar(132), null),
  2287.             cRefCol12 = convert(nvarchar(132), null),
  2288.             cRefCol13 = convert(nvarchar(132), null),
  2289.             cRefCol14 = convert(nvarchar(132), null),
  2290.             cRefCol15 = convert(nvarchar(132), null),
  2291.             cRefCol16 = convert(nvarchar(132), null),
  2292.             cIndexID,
  2293.             cGroupName,
  2294.          cDisabled,
  2295.           cPrimaryFG,
  2296.          cDeleteCascade,
  2297.          cUpdateCascade,
  2298.          Descending = t.cPK
  2299.         from #spkeys, #tempID2 t where cType in (1, 2)
  2300.          and cName = t.cPKName
  2301.             and (@colname is null or
  2302.                 index_col(@tablename, cIndexID, 1) = @colname or
  2303.                 index_col(@tablename, cIndexID, 2) = @colname or
  2304.                 index_col(@tablename, cIndexID, 3) = @colname or
  2305.                 index_col(@tablename, cIndexID, 4) = @colname or
  2306.                 index_col(@tablename, cIndexID, 5) = @colname or
  2307.                 index_col(@tablename, cIndexID, 6) = @colname or
  2308.                 index_col(@tablename, cIndexID, 7) = @colname or
  2309.                 index_col(@tablename, cIndexID, 8) = @colname or
  2310.                 index_col(@tablename, cIndexID, 9) = @colname or
  2311.                 index_col(@tablename, cIndexID, 10) = @colname or
  2312.                 index_col(@tablename, cIndexID, 11) = @colname or
  2313.                 index_col(@tablename, cIndexID, 12) = @colname or
  2314.                 index_col(@tablename, cIndexID, 13) = @colname or
  2315.                 index_col(@tablename, cIndexID, 14) = @colname or
  2316.                 index_col(@tablename, cIndexID, 15) = @colname or
  2317.                 index_col(@tablename, cIndexID, 16) = @colname
  2318.             )
  2319.         UNION
  2320.         select c.cType, c.cName, c.cFlags, c.cColCount, c.cFillFactor, c.cRefTable, c.cRefKey,
  2321.             cKeyCol1 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey1)),
  2322.             cKeyCol2 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey2)),
  2323.             cKeyCol3 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey3)),
  2324.             cKeyCol4 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey4)),
  2325.             cKeyCol5 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey5)),
  2326.             cKeyCol6 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey6)),
  2327.             cKeyCol7 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey7)),
  2328.             cKeyCol8 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey8)),
  2329.             cKeyCol9 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey9)),
  2330.             cKeyCol10 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey10)),
  2331.             cKeyCol11 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey11)),
  2332.             cKeyCol12 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey12)),
  2333.             cKeyCol13 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey13)),
  2334.             cKeyCol14 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey14)),
  2335.             cKeyCol15 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey15)),
  2336.             cKeyCol16 = convert(nvarchar(132), col_name(r.fkeyid, r.fkey16)),
  2337.             cRefCol1 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey1)),
  2338.             cRefCol2 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey2)),    
  2339.             cRefCol3 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey3)),
  2340.             cRefCol4 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey4)),
  2341.             cRefCol5 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey5)),
  2342.             cRefCol6 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey6)),
  2343.             cRefCol7 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey7)),
  2344.             cRefCol8 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey8)),
  2345.             cRefCol9 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey9)),
  2346.             cRefCol10 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey10)),
  2347.             cRefCol11 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey11)),
  2348.             cRefCol12 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey12)),
  2349.             cRefCol13 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey13)),
  2350.             cRefCol14 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey14)),
  2351.             cRefCol15 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey15)),
  2352.             cRefCol16 = convert(nvarchar(132), col_name(r.rkeyid, r.rkey16)),
  2353.             cIndexID,
  2354.             cGroupName,
  2355.          cDisabled,
  2356.           cPrimaryFG,
  2357.          cDeleteCascade,
  2358.          cUpdateCascade,
  2359.          0
  2360.         from #spkeys c, dbo.sysreferences r where c.cType = 3 and r.constid = c.cConstID
  2361.             and (@colname is null or
  2362.                 col_name(r.fkeyid, r.fkey1) = @colname or
  2363.                 col_name(r.fkeyid, r.fkey2) = @colname or
  2364.                 col_name(r.fkeyid, r.fkey3) = @colname or
  2365.                 col_name(r.fkeyid, r.fkey4) = @colname or
  2366.                 col_name(r.fkeyid, r.fkey5) = @colname or
  2367.                 col_name(r.fkeyid, r.fkey6) = @colname or
  2368.                 col_name(r.fkeyid, r.fkey7) = @colname or
  2369.                 col_name(r.fkeyid, r.fkey8) = @colname or
  2370.                 col_name(r.fkeyid, r.fkey9) = @colname or
  2371.                 col_name(r.fkeyid, r.fkey10) = @colname or
  2372.                 col_name(r.fkeyid, r.fkey11) = @colname or
  2373.                 col_name(r.fkeyid, r.fkey12) = @colname or
  2374.                 col_name(r.fkeyid, r.fkey13) = @colname or
  2375.                 col_name(r.fkeyid, r.fkey14) = @colname or
  2376.                 col_name(r.fkeyid, r.fkey15) = @colname or
  2377.                 col_name(r.fkeyid, r.fkey16) = @colname
  2378.             )
  2379.         order by cType, cName
  2380.  
  2381.     if (@flags & 1 <> 0)
  2382.         exec sp_MStablerefs @tablename, N'actualkeycols', N'foreign'
  2383.  
  2384. go
  2385. /* End sp_MStablekeys */
  2386.  
  2387. /*-----------------------------------------------------*/
  2388. /*-----------------------------------------------------*/
  2389. print N''
  2390. print N'Creating sp_MStablechecks'
  2391. print N''
  2392. go
  2393.  
  2394. create procedure sp_MStablechecks
  2395.     @tablename nvarchar(517), @flags int = null
  2396. as
  2397.    /*** @flags added for DaVinci uses.  If the bit isn't set, use 6.5 ***/
  2398.    /*** sp_MStablechecks '%s'                                        ***/
  2399.  
  2400.     declare @id int
  2401.     select @id = object_id(@tablename)
  2402.     if (@id is null) begin
  2403.         RAISERROR (15001, -1, -1, @tablename)
  2404.         return 1
  2405.     end
  2406.  
  2407.     /* @flags is for daVinci. */
  2408.     if (@flags is null)
  2409.         select @flags = 0
  2410.  
  2411.     /* We'll put out the check text if it's all in one row (most likely); otherwise leave it */
  2412.     /* blank for refetching in its entirety via sp_helptext, unless @flags wants it anyway. */
  2413.     select object_name(t.id),
  2414.         case when (@flags & 1 <> 0 or not exists (select * from dbo.syscomments where id = t.id and colid = 2))
  2415.                 then t.text else null end,
  2416.         c.status & (convert(int, 0x00200000) | convert(int, 0x00020000) | convert(int, 0x00004000)),
  2417.       OBJECTPROPERTY( t.id, N'CnstIsDisabled' )
  2418.     from dbo.syscomments t, dbo.sysconstraints c
  2419.     where t.id = c.constid and c.id = @id and c.status & 0x0f = 4
  2420.         and (@flags & 1 <> 0 or t.colid = 1)
  2421.     order by object_name(t.id), t.colid
  2422. go
  2423. /* End sp_MStablechecks */
  2424.  
  2425. /*-----------------------------------------------------*/
  2426. /*-----------------------------------------------------*/
  2427. print N''
  2428. print N'Creating sp_MSsettopology'
  2429. print N''
  2430. go
  2431.  
  2432. /* Need this because it will set sysservers columns. */
  2433. sp_configure N'allow updates', 1
  2434. go
  2435. reconfigure with override
  2436. go
  2437.  
  2438. create procedure sp_MSsettopology
  2439.     @server nvarchar(258), @X int, @Y int
  2440. as
  2441.     update master.dbo.sysservers set topologyx = @X, topologyy = @Y
  2442.         where srvname = @server
  2443.     if (@@rowcount = 0) begin
  2444.         RAISERROR (15015, -1, -1, @server)
  2445.         return 1
  2446.     end
  2447.     return 0
  2448. go
  2449. /* End sp_MSsettopology */
  2450.  
  2451. sp_configure N'allow updates', 0
  2452. go
  2453. reconfigure with override
  2454. go
  2455.  
  2456. /*-----------------------------------------------------*/
  2457. /*-----------------------------------------------------*/
  2458. print N''
  2459. print N'Creating sp_MSmatchkey'
  2460. print N''
  2461. go
  2462.  
  2463. create proc sp_MSmatchkey
  2464.     @tablename nvarchar(517),
  2465.     @col1 nvarchar(258),
  2466.     @col2 nvarchar(258) = null,
  2467.     @col3 nvarchar(258) = null,
  2468.     @col4 nvarchar(258) = null,
  2469.     @col5 nvarchar(258) = null,
  2470.     @col6 nvarchar(258) = null,
  2471.     @col7 nvarchar(258) = null,
  2472.     @col8 nvarchar(258) = null,
  2473.     @col9 nvarchar(258) = null,
  2474.     @col10 nvarchar(258) = null,
  2475.     @col11 nvarchar(258) = null,
  2476.     @col12 nvarchar(258) = null,
  2477.     @col13 nvarchar(258) = null,
  2478.     @col14 nvarchar(258) = null,
  2479.     @col15 nvarchar(258) = null,
  2480.     @col16 nvarchar(258) = null
  2481. as
  2482.  
  2483.     create table #t1 (        /* Join into this... */
  2484.         i                    int                NOT NULL,
  2485.         name                nvarchar(258)     COLLATE database_default   NULL
  2486.     )
  2487.  
  2488.     create table #i1 (
  2489.         i                    int                NOT NULL
  2490.     )
  2491.  
  2492.     declare @id int, @ii int, @colnotfound nvarchar(258), @keycnt int
  2493.     select @id = object_id(@tablename)
  2494.     if (@id is null) begin
  2495.         RAISERROR (15001, -1, -1, @tablename)
  2496.         return 1
  2497.     end
  2498.     select @ii = 1
  2499.     insert #t1 values (1, @col1)
  2500.     insert #t1 values (2, @col2)
  2501.     insert #t1 values (3, @col3)
  2502.     insert #t1 values (4, @col4)
  2503.     insert #t1 values (5, @col5)
  2504.     insert #t1 values (6, @col6)
  2505.     insert #t1 values (7, @col7)
  2506.     insert #t1 values (8, @col8)
  2507.     insert #t1 values (9, @col9)
  2508.     insert #t1 values (10, @col10)
  2509.     insert #t1 values (11, @col11)
  2510.     insert #t1 values (12, @col12)
  2511.     insert #t1 values (13, @col13)
  2512.     insert #t1 values (14, @col14)
  2513.     insert #t1 values (15, @col15)
  2514.     insert #t1 values (16, @col16)
  2515.     delete #t1 where name is null
  2516.  
  2517.     select @colnotfound = min(name) from #t1 where name not in (select name from dbo.syscolumns where id = @id)
  2518.     if (@colnotfound is not null) begin
  2519.         RAISERROR (15253, -1, -1, @colnotfound, @tablename)
  2520.         return 1
  2521.     end
  2522.     select @ii = 1, @keycnt = count(*) from #t1
  2523.  
  2524.     /* Load all indexes which have the matching number of columns into a temp table, then eliminate those which don't qualify. */
  2525.     /* Remember the RID in the nc index is counted as a key */
  2526.     insert #i1 select indid from dbo.sysindexes where status & 0x1800 <> 0
  2527.         and id = @id and keycnt - (case indid when 1 then 0 else 1 end) = @keycnt
  2528.     while (@ii <= @keycnt) begin
  2529.         delete #i1 from #i1 i, #t1 t where t.i = @ii and index_col(@tablename, i.i, t.i) <> t.name
  2530.         select @ii = @ii + 1
  2531.     end
  2532.  
  2533.     /* The qualifying key will be the lowest indid (or the ONLY indid, if we disallow duplicate indexes), if any remain. */
  2534.     select name from dbo.sysindexes where id = @id and indid = (select min(i) from #i1)
  2535. go
  2536. /* End sp_MSmatchkey */
  2537.  
  2538. /*-----------------------------------------------------*/
  2539. /*-----------------------------------------------------*/
  2540. print N''
  2541. print N'Creating sp_MSforeach_worker'
  2542. print N''
  2543. go
  2544.  
  2545. /*
  2546.  * This is the worker proc for all of the "for each" type procs.  Its function is to read the
  2547.  * next replacement name from the cursor (which returns only a single name), plug it into the
  2548.  * replacement locations for the commands, and execute them.  It assumes the cursor "hCForEach"
  2549.  * has already been opened by its caller.
  2550.  */
  2551. create proc sp_MSforeach_worker
  2552.     @command1 nvarchar(2000), @replacechar nchar(1) = N'?', @command2 nvarchar(2000) = null, @command3 nvarchar(2000) = null
  2553. as
  2554.  
  2555.     create table #qtemp (    /* Temp command storage */
  2556.         qnum                int                NOT NULL,
  2557.         qchar                nvarchar(2000)    COLLATE database_default NULL
  2558.     )
  2559.  
  2560.     set nocount on
  2561.     declare @name nvarchar(517), @namelen int, @q1 nvarchar(2000), @q2 nvarchar(2000)
  2562.    declare @q3 nvarchar(2000), @q4 nvarchar(2000), @q5 nvarchar(2000)
  2563.     declare @q6 nvarchar(2000), @q7 nvarchar(2000), @q8 nvarchar(2000), @q9 nvarchar(2000), @q10 nvarchar(2000)
  2564.     declare @cmd nvarchar(2000), @replacecharindex int, @useq tinyint, @usecmd tinyint, @nextcmd nvarchar(2000)
  2565.    declare @namesave nvarchar(517), @nametmp nvarchar(517), @nametmp2 nvarchar(258)
  2566.  
  2567.     open hCForEach
  2568.     fetch hCForEach into @name
  2569.  
  2570.     /* Loop for each database */
  2571.     while (@@fetch_status >= 0) begin
  2572.         /* Initialize. */
  2573.  
  2574.       /* save the original dbname */
  2575.       select @namesave = @name
  2576.         select @useq = 1, @usecmd = 1, @cmd = @command1, @namelen = datalength(@name)
  2577.         while (@cmd is not null) begin        /* Generate @q* for exec() */
  2578.             /*
  2579.              * Parse each @commandX into a single executable batch.
  2580.              * Because the expanded form of a @commandX may be > OSQL_MAXCOLLEN_SET, we'll need to allow overflow.
  2581.              * We also may append @commandX's (signified by '++' as first letters of next @command).
  2582.              */
  2583.             select @replacecharindex = charindex(@replacechar, @cmd)
  2584.             while (@replacecharindex <> 0) begin
  2585.  
  2586.             /* 7.0, if name contains ' character, and the name has been single quoted in command, double all of them in dbname */
  2587.             /* if the name has not been single quoted in command, do not doulbe them */
  2588.             /* if name contains ] character, and the name has been [] quoted in command, double all of ] in dbname */
  2589.             select @name = @namesave
  2590.             select @namelen = datalength(@name)
  2591.             declare @tempindex int
  2592.             if (substring(@cmd, @replacecharindex - 1, 1) = N'''') begin
  2593.                /* if ? is inside of '', we need to double all the ' in name */
  2594.                select @name = REPLACE(@name, N'''', N'''''')
  2595.             end else if (substring(@cmd, @replacecharindex - 1, 1) = N'[') begin
  2596.                /* if ? is inside of [], we need to double all the ] in name */
  2597.                select @name = REPLACE(@name, N']', N']]')
  2598.             end else if ((@name LIKE N'%].%]') and (substring(@name, 1, 1) = N'[')) begin
  2599.                /* ? is NOT inside of [] nor '', and the name is in [owner].[name] format, handle it */
  2600.                /* !!! work around, when using LIKE to find string pattern, can't use '[', since LIKE operator is treating '[' as a wide char */
  2601.                select @tempindex = charindex(N'].[', @name)
  2602.                select @nametmp  = substring(@name, 2, @tempindex-2 )
  2603.                select @nametmp2 = substring(@name, @tempindex+3, len(@name)-@tempindex-3 )
  2604.                select @nametmp  = REPLACE(@nametmp, N']', N']]')
  2605.                select @nametmp2 = REPLACE(@nametmp2, N']', N']]')
  2606.                select @name = N'[' + @nametmp + N'].[' + @nametmp2 + ']'
  2607.             end else if ((@name LIKE N'%]') and (substring(@name, 1, 1) = N'[')) begin
  2608.                /* ? is NOT inside of [] nor '', and the name is in [name] format, handle it */
  2609.                /* j.i.c., since we should not fall into this case */
  2610.                /* !!! work around, when using LIKE to find string pattern, can't use '[', since LIKE operator is treating '[' as a wide char */
  2611.                select @nametmp = substring(@name, 2, len(@name)-2 )
  2612.                select @nametmp = REPLACE(@nametmp, N']', N']]')
  2613.                select @name = N'[' + @nametmp + N']'
  2614.             end
  2615.             /* Get the new length */
  2616.             select @namelen = datalength(@name)
  2617.  
  2618.             /* start normal process */
  2619.                 if (datalength(@cmd) + @namelen - 1 > 2000) begin
  2620.                     /* Overflow; put preceding stuff into the temp table */
  2621.                     if (@useq > 9) begin
  2622.                         raiserror 55555 N'sp_MSforeach_worker assert failed:  command too long'
  2623.                         close hCForEach
  2624.                         deallocate hCForEach
  2625.                         return 1
  2626.                     end
  2627.                     if (@replacecharindex < @namelen) begin
  2628.                         /* If this happened close to beginning, make sure expansion has enough room. */
  2629.                         /* In this case no trailing space can occur as the row ends with @name. */
  2630.                         select @nextcmd = substring(@cmd, 1, @replacecharindex)
  2631.                         select @cmd = substring(@cmd, @replacecharindex + 1, 2000)
  2632.                         select @nextcmd = stuff(@nextcmd, @replacecharindex, 1, @name)
  2633.                         select @replacecharindex = charindex(@replacechar, @cmd)
  2634.                         insert #qtemp values (@useq, @nextcmd)
  2635.                         select @useq = @useq + 1
  2636.                         continue
  2637.                     end
  2638.                     /* Move the string down and stuff() in-place. */
  2639.                     /* Because varchar columns trim trailing spaces, we may need to prepend one to the following string. */
  2640.                     /* In this case, the char to be replaced is moved over by one. */
  2641.                     insert #qtemp values (@useq, substring(@cmd, 1, @replacecharindex - 1))
  2642.                     if (substring(@cmd, @replacecharindex - 1, 1) = N' ') begin
  2643.                         select @cmd = N' ' + substring(@cmd, @replacecharindex, 2000)
  2644.                         select @replacecharindex = 2
  2645.                     end else begin
  2646.                         select @cmd = substring(@cmd, @replacecharindex, 2000)
  2647.                         select @replacecharindex = 1
  2648.                     end
  2649.                     select @useq = @useq + 1
  2650.                 end
  2651.                 select @cmd = stuff(@cmd, @replacecharindex, 1, @name)
  2652.                 select @replacecharindex = charindex(@replacechar, @cmd)
  2653.             end
  2654.  
  2655.             /* Done replacing for current @cmd.  Get the next one and see if it's to be appended. */
  2656.             select @usecmd = @usecmd + 1
  2657.             select @nextcmd = case (@usecmd) when 2 then @command2 when 3 then @command3 else null end
  2658.             if (@nextcmd is not null and substring(@nextcmd, 1, 2) = N'++') begin
  2659.                 insert #qtemp values (@useq, @cmd)
  2660.                 select @cmd = substring(@nextcmd, 3, 2000), @useq = @useq + 1
  2661.                 continue
  2662.             end
  2663.  
  2664.             /* Now exec() the generated @q*, and see if we had more commands to exec().  Continue even if errors. */
  2665.             /* Null them first as the no-result-set case won't. */
  2666.             select @q1 = null, @q2 = null, @q3 = null, @q4 = null, @q5 = null, @q6 = null, @q7 = null, @q8 = null, @q9 = null, @q10 = null
  2667.             select @q1 = qchar from #qtemp where qnum = 1
  2668.             select @q2 = qchar from #qtemp where qnum = 2
  2669.             select @q3 = qchar from #qtemp where qnum = 3
  2670.             select @q4 = qchar from #qtemp where qnum = 4
  2671.             select @q5 = qchar from #qtemp where qnum = 5
  2672.             select @q6 = qchar from #qtemp where qnum = 6
  2673.             select @q7 = qchar from #qtemp where qnum = 7
  2674.             select @q8 = qchar from #qtemp where qnum = 8
  2675.             select @q9 = qchar from #qtemp where qnum = 9
  2676.             select @q10 = qchar from #qtemp where qnum = 10
  2677.             truncate table #qtemp
  2678.             exec (@q1 + @q2 + @q3 + @q4 + @q5 + @q6 + @q7 + @q8 + @q9 + @q10 + @cmd)
  2679.             select @cmd = @nextcmd, @useq = 1
  2680.         end /* while @cmd is not null, generating @q* for exec() */
  2681.  
  2682.         /* All commands done for this name.  Go to next one. */
  2683.         fetch hCForEach into @name
  2684.     end /* while FETCH_SUCCESS */
  2685.     close hCForEach
  2686.     deallocate hCForEach
  2687.     return 0
  2688. go
  2689.  
  2690. /* End sp_MSforeach_worker */
  2691.  
  2692. /*-----------------------------------------------------*/
  2693. /*-----------------------------------------------------*/
  2694. print N''
  2695. print N'Creating sp_MSforeachdb'
  2696. print N''
  2697. go
  2698.  
  2699. /*
  2700.  * The following table definition will be created by SQLDMO at start of each connection.
  2701.  * We don't create it here temporarily because we need it in Exec() or upgrade won't work.
  2702.  */
  2703.  
  2704. create proc sp_MSforeachdb
  2705.     @command1 nvarchar(2000), @replacechar nchar(1) = N'?', @command2 nvarchar(2000) = null, @command3 nvarchar(2000) = null,
  2706.     @precommand nvarchar(2000) = null, @postcommand nvarchar(2000) = null
  2707. as
  2708.     set deadlock_priority low
  2709.     
  2710.     /* This proc returns one or more rows for each accessible db, with each db defaulting to its own result set */
  2711.     /* @precommand and @postcommand may be used to force a single result set via a temp table. */
  2712.  
  2713.     /* Preprocessor won't replace within quotes so have to use str(). */
  2714.     declare @inaccessible nvarchar(12), @invalidlogin nvarchar(12), @dbinaccessible nvarchar(12)
  2715.     select @inaccessible = ltrim(str(convert(int, 0x03e0), 11))
  2716.     select @invalidlogin = ltrim(str(convert(int, 0x40000000), 11))
  2717.     select @dbinaccessible = N'0x80000000'        /* SQLDMODbUserProf_InaccessibleDb; the negative number doesn't work in convert() */
  2718.  
  2719.     if (@precommand is not null)
  2720.         exec(@precommand)
  2721.  
  2722.     declare @origdb nvarchar(128)
  2723.     select @origdb = db_name()
  2724.  
  2725.     /* If it's a single user db and there's an entry for it in sysprocesses who isn't us, we can't use it. */
  2726.    /* Create the select */
  2727.     exec(N'declare hCForEach cursor global for select name from master.dbo.sysdatabases d ' +
  2728.             N' where (d.status & ' + @inaccessible + N' = 0)' +
  2729.             N' and ((DATABASEPROPERTY(d.name, ''issingleuser'') = 0 and (has_dbaccess(d.name) = 1)) or ' +
  2730.             N' ( DATABASEPROPERTY(d.name, ''issingleuser'') = 1 and not exists ' +
  2731.             N' (select * from master.dbo.sysprocesses p where dbid = d.dbid and p.spid <> @@spid)))' )
  2732.  
  2733.     declare @retval int
  2734.     select @retval = @@error
  2735.     if (@retval = 0)
  2736.         exec @retval = sp_MSforeach_worker @command1, @replacechar, @command2, @command3
  2737.  
  2738.     if (@retval = 0 and @postcommand is not null)
  2739.         exec(@postcommand)
  2740.  
  2741.    declare @tempdb nvarchar(258)
  2742.    SELECT @tempdb = REPLACE(@origdb, N']', N']]')
  2743.    exec (N'use ' + N'[' + @tempdb + N']')
  2744.  
  2745.     return @retval
  2746. go
  2747. /* End sp_MSforeachdb */
  2748.  
  2749. /*-----------------------------------------------------*/
  2750. /*-----------------------------------------------------*/
  2751. print N''
  2752. print N'Creating sp_MSforeachtable'
  2753. print N''
  2754. go
  2755.  
  2756. create proc sp_MSforeachtable
  2757.     @command1 nvarchar(2000), @replacechar nchar(1) = N'?', @command2 nvarchar(2000) = null,
  2758.    @command3 nvarchar(2000) = null, @whereand nvarchar(2000) = null,
  2759.     @precommand nvarchar(2000) = null, @postcommand nvarchar(2000) = null
  2760. as
  2761.     /* This proc returns one or more rows for each table (optionally, matching @where), with each table defaulting to its own result set */
  2762.     /* @precommand and @postcommand may be used to force a single result set via a temp table. */
  2763.  
  2764.     /* Preprocessor won't replace within quotes so have to use str(). */
  2765.     declare @mscat nvarchar(12)
  2766.     select @mscat = ltrim(str(convert(int, 0x0002)))
  2767.  
  2768.     if (@precommand is not null)
  2769.         exec(@precommand)
  2770.  
  2771.     /* Create the select */
  2772.    exec(N'declare hCForEach cursor global for select ''['' + REPLACE(user_name(uid), N'']'', N'']]'') + '']'' + ''.'' + ''['' + REPLACE(object_name(id), N'']'', N'']]'') + '']'' from dbo.sysobjects o '
  2773.          + N' where OBJECTPROPERTY(o.id, N''IsUserTable'') = 1 ' + N' and o.category & ' + @mscat + N' = 0 '
  2774.          + @whereand)
  2775.     declare @retval int
  2776.     select @retval = @@error
  2777.     if (@retval = 0)
  2778.         exec @retval = sp_MSforeach_worker @command1, @replacechar, @command2, @command3
  2779.  
  2780.     if (@retval = 0 and @postcommand is not null)
  2781.         exec(@postcommand)
  2782.  
  2783.     return @retval
  2784. go
  2785. /* End sp_MSforeachtable */
  2786.  
  2787. /*******************************************************************************/
  2788.  
  2789. print N''
  2790. print N'Creating sp_MSloginmappings'
  2791. print N''
  2792. go
  2793.  
  2794.  
  2795.  
  2796. create proc sp_MSloginmappings
  2797.     @loginname nvarchar(258) = null, @flags int = 0
  2798. as
  2799.  
  2800.     create table #loginmappings(
  2801.         LoginName  nvarchar(128) NULL,
  2802.         DBName     nvarchar(128) NULL,
  2803.         UserName   nvarchar(128) NULL,
  2804.         AliasName  nvarchar(128) NULL
  2805.     )
  2806.  
  2807.     /*
  2808.      * @flags bits:
  2809.      *        0x01    - current db only
  2810.      */
  2811.     /*
  2812.      * Added @dbname so dbo can see everyone in current database.
  2813.      * Use hacky 4.21 syntax so it will run there, instead of a case..when.
  2814.      */
  2815.     declare @checkmultilogin int
  2816.     select @checkmultilogin = 1
  2817.     if ((@flags & 0x01 <> 0) and user_id() = 1)
  2818.         select @checkmultilogin = 0
  2819.  
  2820.     declare @logincount int
  2821.     select @logincount = 0
  2822.     if (@loginname is not null)
  2823.         select @logincount = count(*) from dbo.syslogins where loginname = @loginname
  2824.  
  2825.     /* Gotta be sa or dbo to see other than just current login. */
  2826.     declare @numlogins int, @whereloginname nvarchar(258), @name nvarchar(258), @retval int
  2827.     if (@loginname is null)
  2828.         select @numlogins = 2
  2829.     else
  2830.         select @numlogins = count(*) from dbo.syslogins where loginname = @loginname
  2831.  
  2832.     if (@numlogins = 0) begin
  2833.         RAISERROR (15007, -1, -1, @loginname)        /* Login not found */
  2834.         return 1
  2835.     end
  2836.     if (@checkmultilogin <> 0) begin
  2837.       /* We do not want to allow everybody to execute this SP */
  2838.         if (is_member(N'db_ddladmin') <> 1 and is_member(N'db_owner') <> 1 and is_member(N'db_accessadmin') <> 1 and is_member(N'db_securityadmin') <> 1 and (@numlogins > 1 or suser_sid() <> suser_sid(@loginname))) begin
  2839.             RAISERROR (14301, -1, -1, N'')                /* Only sa can see other than the current login */
  2840.             return 1
  2841.         end
  2842.     end
  2843.     if (@loginname is not null)
  2844.         select @whereloginname = N' and loginname = ''' + @loginname + N''''
  2845.    else
  2846.       select @whereloginname = N' '
  2847.  
  2848.     /*
  2849.      * This proc returns a result set with one or more rows for each database for which a login is a user or aliased to one.
  2850.      * If loginname is specified, the results are limited to that login.  First load a temp table with all logins that are
  2851.      * in a db, then add those which aren't mapped to any db.
  2852.      */
  2853.     if (@flags & 0x01 <> 0) begin
  2854.         INSERT #loginmappings select l.loginname, db_name(), u.name, null from master.dbo.syslogins l, dbo.sysusers u where l.sid = u.sid and l.loginname is not NULL
  2855.         /*
  2856.          * We only allow multi-db on a 6.x server because dynamic exec() didn't exist before then,
  2857.          * hence there is no way to loop thru every database.  This is caught in SQLDMO so no
  2858.          * need for error message here; we'll just return no result sets.
  2859.          */
  2860.     end else begin
  2861.         exec @retval = sp_MSforeachdb
  2862.             N'use [?] INSERT #loginmappings select l.loginname, db_name(), u.name, null from master.dbo.syslogins l, dbo.sysusers u where l.sid = u.sid and l.loginname is not NULL'
  2863.         if (@retval <> 0)
  2864.             return 1
  2865.         insert #loginmappings select l.loginname, null, null, null from master.dbo.syslogins l where l.loginname not in (select LoginName from #loginmappings) and l.loginname is not NULL
  2866.     end
  2867.  
  2868.     /*
  2869.      * Now bring them out by loginname, each in its own result set.
  2870.      * If this is for all logins, we'll return all logins; if for curdb,
  2871.      * only those in #loginmappings (i.e. only those mapped in curdb).
  2872.      */
  2873.     exec(N'declare hCForEachLogin cursor global for select loginname from master.dbo.syslogins where loginname is not NULL ' + @whereloginname + N' order by loginname')
  2874.     if (@@error = 0)
  2875.         open hCForEachLogin
  2876.     if (@@error <> 0)
  2877.         return @@error
  2878.     fetch hCForEachLogin into @name
  2879.     while (@@fetch_status >= 0) begin
  2880.       /* Use '=' instead of 'LIKE' in comparision, so we can handle wide card character correctly */
  2881.         if ((@flags & 0x01 = 0) or exists (select * from #loginmappings where LoginName = @name))
  2882.             select * from #loginmappings where LoginName = @name
  2883.         fetch hCForEachLogin into @name
  2884.     end /* FETCH_SUCCESS */
  2885.     close hCForEachLogin
  2886.     deallocate hCForEachLogin
  2887.     return @@error
  2888. go
  2889. /* End sp_MSloginmappings */
  2890.  
  2891. /*******************************************************************************/
  2892. print N''
  2893. print N'Creating sp_MSuniquename'
  2894. print N''
  2895. go
  2896.  
  2897. create procedure sp_MSuniquename
  2898.     @seed nvarchar(128), @start int = null
  2899. as
  2900.     /* Return a unique name for sysobjects, based on a passed-in seed. */
  2901.     set nocount on
  2902.     declare @i int, @append nvarchar(10), @seedlen int, @temp nvarchar(128), @recalcseedlen int, @seedcharlen int
  2903.     select @i = 1, @seedlen = datalength(@seed), @recalcseedlen = 1, @seedcharlen = 0
  2904.     if (@start is not null and @start >= 0)
  2905.         select @i = @start
  2906.     while 1 < 2
  2907.     begin
  2908.         /* This is probably overkill, but start at max length of seed name, leaving room under OSQL_DBLSYSNAME_SET for @append. */
  2909.         /* We'll work our way back along the string if more room needed (pathological user). */
  2910.         select @append = ltrim(str(@i)) + N'__' + ltrim(str(@@spid))
  2911.         if (@recalcseedlen = @i or @seedcharlen = 0)
  2912.         begin
  2913.             while @recalcseedlen <= @i
  2914.                 select @recalcseedlen = @recalcseedlen * 10
  2915.             select @seedcharlen = @seedlen
  2916.             if ((@seedlen + datalength(@append)) > 128) begin
  2917.                 select @seedlen = 128 - datalength(@append)
  2918.  
  2919.                 /* Get the charlen of this datalength for the substring() call. */
  2920.                 select @seedcharlen = @seedlen
  2921.                /* exec sp_GetMBCSCharLen @seed, @seedlen, @seedcharlen out */
  2922.             end        /* Recalc seedlen */
  2923.         end        /* Check seedlen */
  2924.  
  2925.         select @temp = substring(@seed, 1, @seedcharlen) + @append
  2926.  
  2927.         /* If I don't set a limit somewhere, it's gonna look hung -- I'd rather get a nonunique error. */
  2928.         if object_id(@temp) is null or @i > 999999        /* if increased, watch out for overflow of @recalcseedlen */
  2929.         begin
  2930.             set nocount off
  2931.             select Name = @temp, Next = @i + 1
  2932.             return 0
  2933.         end
  2934.         select @i = @i + 1
  2935.     end
  2936. go
  2937. /* End sp_MSuniquename */
  2938.  
  2939. /*******************************************************************************/
  2940. print N''
  2941. print N'Creating sp_MSkilldb'
  2942. print N''
  2943. go
  2944.  
  2945. sp_configure updat, 1
  2946. go
  2947. reconfigure with override
  2948. go
  2949.  
  2950. create proc sp_MSkilldb
  2951.     @dbname nvarchar(258)
  2952. as
  2953.     if (@@trancount > 0) begin
  2954.         RAISERROR (15002, -1, -1, N'sp_MSkilldb')
  2955.         return 1
  2956.     end
  2957.  
  2958.     if (is_member(N'db_owner') <> 1 and is_member(N'db_ddladmin') <> 1) begin
  2959.         RAISERROR (15003, -1, -1, N'')
  2960.         return 1
  2961.     end
  2962.  
  2963.     /* Set this db to suspect, then let dbcc dbrepair kill it for us. */
  2964.     update master.dbo.sysdatabases set status = status | 0x0100
  2965.         where name = @dbname
  2966.     if (@@rowcount = 0) begin
  2967.         declare @len int
  2968.         select @len = datalength(@dbname)
  2969.         RAISERROR (2702, -1, -1, @len, @dbname)
  2970.         return 1
  2971.     end
  2972.     dbcc dbrepair(@dbname, dropdb)
  2973.     return 0
  2974. go
  2975.  
  2976. sp_configure updat, 0
  2977. go
  2978. reconfigure with override
  2979. go
  2980.  
  2981. /* End sp_MSkilldb */
  2982.  
  2983. /*******************************************************************************/
  2984. print N''
  2985. print N'Creating sp_MSobjectprivs'
  2986. print N''
  2987. go
  2988.  
  2989. create proc sp_MSobjectprivs
  2990.     @objname nvarchar(776) = null,
  2991.     @mode nvarchar(10) = N'object',    
  2992.     @objid int = null,                
  2993.     @srvpriv int = null,            
  2994.     @prottype int = null,            
  2995.     @grantee nvarchar(258) = null,        
  2996.    @flags int = 0,
  2997.    @rollup int = 0
  2998. as
  2999.  
  3000.     create table #objs(
  3001.         id  int NOT NULL
  3002.     )
  3003.  
  3004.     /* Temp table will hold output for final select */
  3005.     create table #output (
  3006.         action      int  NOT NULL,
  3007.         colid       int  NULL,
  3008.         uid         int  NOT NULL,
  3009.         protecttype int  NOT NULL,
  3010.         id          int  NOT NULL,
  3011.         grantor     int
  3012.     )
  3013.  
  3014.     create table #tmp(
  3015.         action   int   NOT NULL,
  3016.         uid      int   NOT NULL,
  3017.         protecttype int  NOT NULL,
  3018.     )
  3019.  
  3020.    /* mode    : 'object', 'user' or 'column'*/
  3021.    /*
  3022.     * Note:  This was expanded for 6.5 due to changes in sysprotects.columns usage, affecting
  3023.     * CPermission::ListPrivilegeColumns.  The following additional parameters are for this.
  3024.     */
  3025.    /* objid   : ID of the object we're querying */
  3026.    /* srvpriv : privilege that we're querying for (e.g. select) */
  3027.    /* prottype: Protect type, e.g. GRANT/REVOKE */
  3028.    /* grantee : Grantee name. */
  3029.  
  3030.    /*** @flags added for DaVinci uses.  If the bit isn't set, use 6.5 ***/
  3031.    /*** sp_MSobjectprivs '%s'                                         ***/
  3032.  
  3033.    /* 8.0: mode 'column', and grantee != null, we want user column level permissions for CTable/CView::ListUserColumnPermissions */
  3034.    /*      @rollup added to indicate special rollup result set for column level permission, set to 1 to roll up */
  3035.  
  3036.     /* @flags is for daVinci */
  3037.     if (@flags is null)
  3038.         select @flags = 0
  3039.  
  3040.     /* If @objid is not null, this is for the new query for perm cols. */
  3041.     if (@objid is not null) begin
  3042.         select u.name, o.name, a = col_name(p.id, a.number), a.low, a.high, a.number
  3043.             from master.dbo.spt_values a, dbo.sysprotects p, dbo.sysobjects o, dbo.sysusers u
  3044.             where p.id = @objid and p.action = @srvpriv and p.protecttype = @prottype
  3045.             and p.uid = user_id(@grantee)
  3046.             and p.columns != 0x01 and o.id = p.id and u.uid = o.uid
  3047.                 and convert(tinyint, substring(isnull(p.columns, 0x01), a.low, 1)) &
  3048.                     -- 6.5 changed so that the bit 0 position is an "invert the bits" indicator:
  3049.                     --        when 0, behaviour is the same as in prior versions, and other bits
  3050.                     --            indicate columns with the specified privilege
  3051.                     --        when 1, the other bits are indicate columns lacking the specified privilege
  3052.                     a.high <> (case when (substring(isnull(p.columns, 0x00), 1, 1) & 1 = 0) then 0 else a.high end)
  3053.                     and col_name(p.id, a.number) is not null
  3054.                     and a.type = N'P' and a.number <= (select count(*) from dbo.syscolumns where id = @objid) order by a
  3055.         return 0
  3056.     end
  3057.  
  3058.     set nocount on
  3059.  
  3060.     /*
  3061.      * To get around a 4.21 subquery bug where returning count(*) of 0 (for proc cols)
  3062.      * causes the result set to return no rows, we need two passes; one to get the
  3063.      * objects, and another to explicitly use a value (@cols) instead of a subquery.
  3064.      */
  3065.     declare @id int, @uid int, @cols int
  3066.     select @id = null, @uid = null
  3067.     if (@mode like N'us%') begin
  3068.        select @uid = user_id(@objname)
  3069.    end else if (@mode like N'col%') and (@objname is null) and (@grantee is not null) begin
  3070.       /* 8.0, special path to get column level permissions from all objects on the specified user */
  3071.       select @uid = user_id(@grantee)
  3072.     end else begin
  3073.       select @id = object_id(@objname)
  3074.    end
  3075.     if (@id is null and @uid is null) begin
  3076.         RAISERROR (15001, -1, -1, @objname)
  3077.         return 1
  3078.     end
  3079.  
  3080.     /* Get a temp list of objects we're interested in.  Do not include repl_* users. */
  3081.    /* This is the original code */
  3082.    insert #objs select distinct p.id from dbo.sysprotects p
  3083.        where (@id is null or p.id = @id)
  3084.           and (@uid is null or p.uid = @uid)
  3085.        and p.action in (193, 195, 196, 197, 224, 26) and p.uid not in (16382, 16383)
  3086.  
  3087.     /* Use a "fake cursor" by deleting successive id's from #objs, as this must run on 4.21 */
  3088.     select @id = min(id) from #objs
  3089.     while (@id is not null) begin
  3090.         select @cols = count(*) from dbo.syscolumns c where c.id = @id
  3091.       /* sysprotects.columns is for SELECT and UPDATE, NULL if it is INSERT or DELETE, since INSERT and DELETE can not be applied to column level */
  3092.       insert #output select p.action, (case when p.columns is null then -1 else a.number end), p.uid, p.protecttype, p.id, p.grantor
  3093.          from master.dbo.spt_values a, dbo.sysprotects p
  3094.          where convert(tinyint, substring( isnull(p.columns, 0x01), a.low, 1)) & a.high !=0
  3095.          and (p.id = @id)
  3096.          and (@uid is null or p.uid = @uid)
  3097.          and a.number <= @cols
  3098.          and a.type = N'P'
  3099.  
  3100.       declare @count int, @whataction int, @whatid int, @dup int, @whatprot int
  3101.  
  3102.       /* First pass to correct duplicates */
  3103.       select @count = count(*) from #output where id = @id and colid in (0, -1) and protecttype in (205, 204)
  3104.       if ( @count > 0 ) begin
  3105.          /* We might have duplicate rows for permission on single coulmn(s) at this point */
  3106.          /* Use a fake cursor to remove the duplicates first. */
  3107.          insert #tmp select action, uid, protecttype from #output where id = @id and colid in (0, -1) and protecttype in (205, 204)
  3108.          select @whataction = min(action) from #tmp
  3109.          select @whatid = uid from #tmp where action = @whataction
  3110.          while (@whataction is not null) begin
  3111.             if (@mode like N'col%') and (@objname is null) and (@grantee is not null) begin
  3112.                /* Special case for column level permissions on ALL objects for the specified user, we don't want the row(s) on the entire table */
  3113.                /* and we don't want the possible duplicate rows in single column(s) */
  3114.                delete #output where (@whatid = uid) and (colid not in (0, -1)) and (protecttype in (205, 204)) and action = @whataction
  3115.                       and (exists (select * from #output where (@whatid = uid) and (colid in (0, -1)) and action = @whataction) and (id = @id))
  3116.                delete #output where (@whatid = uid) and (colid in (0, -1)) and (action = @whataction) and (id = @id)
  3117.             end else if (@mode like N'use%') and (@objname is not null) begin
  3118.                /* Special case for the user mode, we do want to keep the entire table permissions */
  3119.                delete #output where (@whatid = uid) and (colid not in (0, -1)) and (protecttype in (205, 204)) and action = @whataction and (id = @id)
  3120.             end else begin
  3121.                /* Other cases */
  3122.                delete #output where (@whatid = uid) and (colid not in (0, -1)) and (protecttype in (205, 204)) and action = @whataction
  3123.             end
  3124.  
  3125.             delete #tmp where @whatid = uid
  3126.             select @whataction = min(action) from #tmp
  3127.             select @whatid = uid from #tmp where action = @whataction
  3128.          end
  3129.          delete #tmp
  3130.       end
  3131.  
  3132.       /* Second pass to correct protect type */
  3133.       select @count = count(*) from #output where id = @id and colid in (0, -1)
  3134.       if ( @count > 0 ) begin
  3135.          /* use another fake cursor to correct the protecttype */
  3136.          /* if there are multiple rows in #output for the same id and action, and if colid = 0 exist */
  3137.          /* then other rows should have different protecttype from the one in colid = 0 row */
  3138.          insert #tmp select action, uid, protecttype from #output where id = @id and colid in (0, -1)
  3139.          select @whataction = min(action) from #tmp
  3140.          select @whatid = uid from #tmp where action = @whataction
  3141.          select @whatprot = protecttype from #tmp where uid = @whatid and action = @whataction
  3142.          while (@whataction is not null) begin
  3143.                delete #output where id = @id and colid not in (0, -1) and @whataction = action and @whatid = uid and @whatprot = protecttype
  3144.                delete #tmp where action = @whataction and @whatid = uid
  3145.                select @whataction = min(action) from #tmp
  3146.                select @whatid = uid from #tmp where action = @whataction
  3147.                select @whatprot = protecttype from #tmp where uid = @whatid and action = @whataction
  3148.          end
  3149.          delete #tmp
  3150.       end
  3151.  
  3152.         /* Increment our "fake cursor" column and get the next one. */
  3153.         delete #objs where id = @id
  3154.         select @id = min(id) from #objs
  3155.     end
  3156.  
  3157.     /*
  3158.      * Organize so that the non-collist privileges are returned first.. this allows
  3159.      * scripting to combine them.  sysprotects.action is tinyint, so the hibyte won't conflict.
  3160.      */
  3161.  
  3162.     update #output set action = action | 0x10000000 where colid <> 0
  3163.  
  3164.     /*
  3165.      *  BUG 235637  
  3166.      *  Delete the columns that was droped
  3167.      */
  3168.     delete from #output where colid not in (0, -1) and col_name(id, colid) is null
  3169.  
  3170.     /*
  3171.      * Order output by uid so Public will script before other groups (we need to script privs for public before
  3172.      * other groups, before users; otherwise sysprotects doesn't hold onto things right).  Sub-order is by object id
  3173.      * so we know when we're done with one object and onto the next, then by protecttype to group all GRANTs and
  3174.      * REVOKEs together, and lastly by action (including ORDER_ACTION_BIT so scripting can be more efficient)
  3175.      * because we may have multiple rows for columns.
  3176.      */
  3177.  
  3178.     set nocount off
  3179.    if (@mode not like N'col%') begin
  3180.       /* Mode is not 'column', do the regular stuff */
  3181.        select p.action & ~convert(int, 0x10000000), N'column' = col_name(p.id, p.colid), p.uid, N'username' = user_name(p.uid),
  3182.                p.protecttype, o.name, N'owner' = user_name(o.uid), p.id, N'grantor' = user_name(p.grantor)
  3183.              from #output p, dbo.sysobjects o
  3184.              where o.id = p.id
  3185.              order by p.uid, p.id, p.protecttype, p.action
  3186.    end else
  3187.    /* Below are spcial cases for column level permissions */
  3188.    if (@objname is null) and (@grantee is not null) and (@rollup = 0) begin
  3189.       /* 8.0, special path to get column level permissions from all objects on the specified user */
  3190.       select N'ObjectName' = o.name, N'Owner' = user_name(o.uid), N'ColumnName' = col_name(p.id, p.colid), o.sysstat & 0x0f, p.id,
  3191.              p.action & ~convert(int, 0x10000000), p.protecttype
  3192.              from #output p, dbo.sysobjects o
  3193.              where p.id = o.id and p.uid = user_id(@grantee) and col_name(p.id, p.colid) is not null
  3194.              order by p.uid, p.id, p.protecttype, p.action
  3195.     end else if (@objname is not null) and (@grantee is not null) and (@rollup = 0) begin
  3196.       /* 8.0, mode 'column', and grantee != null, we want column level permissions on this object for this user */
  3197.       select N'column' = col_name(p.id, p.colid), N'owner' = user_name(o.uid), N'username' = user_name(p.uid), o.sysstat & 0x0f, p.id,
  3198.              p.action & ~convert(int, 0x10000000), p.protecttype
  3199.              from #output p, dbo.sysobjects o
  3200.              where o.id = p.id and p.uid = user_id(@grantee) and col_name(p.id, p.colid) is not null
  3201.              order by p.uid, p.id, p.protecttype, p.action
  3202.    end else if (@objname is not null) and (@grantee is null) and (@rollup = 0) begin
  3203.       /* 8.0, mode 'column', and grantee = null, we want column level permissions on this object for all users */
  3204.       select N'column' = col_name(p.id, p.colid), N'owner' = user_name(o.uid), N'username' = user_name(p.uid), o.sysstat & 0x0f, p.id,
  3205.              p.action & ~convert(int, 0x10000000), p.protecttype
  3206.              from #output p, dbo.sysobjects o
  3207.              where o.id = p.id and col_name(p.id, p.colid) is not null
  3208.              order by p.uid, p.id, p.protecttype, p.action
  3209.    end else if (@objname is null) and (@grantee is not null) and (@rollup <> 0) begin
  3210.       /* 8.0, roll up version of the special path to get column level permissions from all objects on the specified user */
  3211.       select distinct N'ObjectName' = o.name, N'owner' = user_name(o.uid),
  3212.              N'Select' = (case when ((p.action & ~convert(int, 0x10000000))=193) then 1 else 0 end),
  3213.              N'Update' = (case when ((p.action & ~convert(int, 0x10000000))=197) then 1 else 0 end),
  3214.              N'Type' = p.protecttype
  3215.              from #output p, dbo.sysobjects o
  3216.              where p.id = o.id and p.uid = user_id(@grantee) and col_name(p.id, p.colid) is not null
  3217.              order by o.name
  3218.    end else if (@objname is not null) and (@grantee is null) and (@rollup <> 0) begin
  3219.       /* 8.0, roll up version of the special path to return column level permissions on this object for all users */
  3220.       select distinct N'UserName' = user_name(p.uid),
  3221.              N'Select' = (case when ((p.action & ~convert(int, 0x10000000))=193) then 1 else 0 end),
  3222.              N'Update' = (case when ((p.action & ~convert(int, 0x10000000))=197) then 1 else 0 end),
  3223.              N'Type' = p.protecttype
  3224.              from #output p, dbo.sysobjects o
  3225.              where o.id = p.id and col_name(p.id, p.colid) is not null
  3226.              order by user_name(p.uid)
  3227.    end else begin
  3228.       raiserror 55555 N'Invalid parameter combinations.'
  3229.         return 1
  3230.    end
  3231. go
  3232. /* End sp_MSobjectprivs */
  3233.  
  3234. /*******************************************************************************/
  3235. /* Need to create the version proc here so we can set its category bit */
  3236. print N''
  3237. print N'Creating sp_MSSQLDMO80_version'
  3238. print N''
  3239. go
  3240.  
  3241. create procedure sp_MSSQLDMO80_version
  3242. as
  3243.     /* Values for this are same as @@microsoftversion */
  3244.    /* @@microsoftversion format is 0xaaiibbbb (aa = major, ii = minor, bb[bb] = build #) */
  3245.     declare @i int
  3246.     select @i = 0x08000000    /* Must be in hex! */
  3247.  
  3248.     /* Select the numeric value, and a conversion to make it readable */
  3249.     select N'Microsoft SQLDMO Scripts' = @i, N'Version' = convert(binary(4), @i)
  3250. go
  3251.  
  3252. /*
  3253.  * The following three scripts must retain the SQLOLE nomenclature as we provide them to be an informative
  3254.  * notification to downlevel connections.
  3255.  */
  3256. create procedure sp_MSSQLDMO70_version
  3257. as
  3258.     RAISERROR 55555 N'You must upgrade your SQL Enterprise Manager and SQL-DMO (SQLOLE) to SQL Server 2000 (SQLDMO) to connect to this server.'
  3259.    return 1
  3260. go
  3261.  
  3262.  
  3263. create procedure sp_MSSQLOLE65_version
  3264. as
  3265.     RAISERROR 55555 N'You must upgrade your SQL Enterprise Manager and SQL-DMO (SQLOLE) to SQL Server 2000 (SQLDMO) to connect to this server.'
  3266.    return 1
  3267. go
  3268.  
  3269. create procedure sp_MSSQLOLE_version
  3270. as
  3271.     RAISERROR 55555 N'You must upgrade your SQL Enterprise Manager and SQL-DMO (SQLOLE) to SQL Server 2000 (SQLDMO) to connect to this server.'
  3272.    return 1
  3273. go
  3274.  
  3275. /*******************************************************************************/
  3276. print N''
  3277. print N'Creating sp_MSscriptdatabase'
  3278. print N''
  3279. go
  3280. create procedure sp_MSscriptdatabase
  3281. @dbname nvarchar(258)
  3282. as
  3283.    /* verify */
  3284.    declare @id int
  3285.    select @id = dbid from master.dbo.sysdatabases where name = @dbname
  3286.    if (@id is null)
  3287.    begin
  3288.       RAISERROR (15001, -1, -1, @dbname)
  3289.       return 1
  3290.    end
  3291.  
  3292.    /* Ready to get to work */
  3293.    declare @dbTempname nvarchar(258)
  3294.    SELECT @dbTempname = REPLACE(@dbname, N']', N']]')
  3295.    exec (N'[' + @dbTempname + N']' + N'..sp_MSscriptdb_worker ')
  3296. go
  3297. /* End sp_MSscriptdatabase */
  3298.  
  3299. /*******************************************************************************/
  3300. print N''
  3301. print N'Creating sp_MSscriptdb_worker'
  3302. print N''
  3303. go
  3304. create procedure sp_MSscriptdb_worker
  3305. as
  3306.  
  3307.     create table #tempFG
  3308.     (
  3309.      cDefault     int,                                  /* 1 for default FG, 0 for user defined */
  3310.      cDBFile      int,                                  /* 1 for DB file, 0 for Log file */
  3311.       cSize        int,                                  /* in 8K page */
  3312.       cMaxSize     int,
  3313.       cGrowth      int,
  3314.      cGrowthType  int,                                  /* 1 for GrowthInMB, 0 for GrowthInPercent */
  3315.      cFGName      nvarchar(132) COLLATE database_default NOT NULL,      /* FG name */
  3316.       cName        nvarchar(132) COLLATE database_default NOT NULL,      /* Logical */
  3317.       cFileName    nvarchar(264) COLLATE database_default NOT NULL,     /* Physical */
  3318.     )
  3319.  
  3320.     create table #tempID
  3321.    (
  3322.         cGroupID int
  3323.     )
  3324.  
  3325.     set nocount on
  3326.  
  3327.    declare @PageSize int;
  3328.    select @PageSize = (low/1024) from master..spt_values where number = 1 and type = N'E'
  3329.  
  3330.    /* Default FileGroup first, which should cover all the log files */
  3331.    /* This one to pick up all the db files in Primary file group, while group id = 1 */
  3332.    insert #tempFG select 1, 1, convert(int, ceiling(((convert(float, o.size) * @PageSize)/1024))), (case when (o.maxsize < 1) then o.maxsize else convert(int, ceiling(((convert(float, o.maxsize) * @PageSize)/1024))) end), o.growth, (case when (o.status & 0x100000 = 0) then 1 else 0 end), g.groupname, RTRIM(o.name), RTRIM(o.filename) from dbo.sysfiles o, dbo.sysfilegroups g where g.groupid = 1 and g.groupid = o.groupid and (o.status & 0x40) = 0
  3333.    /* This one to pick up all the log files in Primary file group, while group id = 0, note that group id 0 does not exist in sysfilegroups */
  3334.    insert #tempFG select 1, 0, (o.size * @PageSize)/1024, (case when (o.maxsize < 1) then o.maxsize else convert(int, ceiling(((convert(float, o.maxsize) * @PageSize)/1024))) end), o.growth, (case when (o.status & 0x100000 = 0) then 1 else 0 end), N'PRIMARY', RTRIM(o.name), RTRIM(o.filename) from dbo.sysfiles o where o.groupid = 0 and (o.status & 0x40) <> 0
  3335.    /* Other FileGroups, we should have DBFiles, no log files */
  3336.  
  3337.    insert #tempID select groupid from dbo.sysfilegroups where groupid <> 1
  3338.  
  3339.    declare @FGid int
  3340.     exec(N'declare hC cursor global for select cGroupID from #tempID')
  3341.     open hC
  3342.     fetch hC into @FGid
  3343.     while (@@fetch_status >= 0) begin
  3344.       insert #tempFG select 0, 1, (o.size * @PageSize)/1024, (case when (o.maxsize < 1) then o.maxsize else convert(int, ceiling(((convert(float, o.maxsize) * @PageSize)/1024))) end), o.growth, (case when (o.status & 0x100000 = 0) then 1 else 0 end), g.groupname, RTRIM(o.name), RTRIM(o.filename) from dbo.sysfiles o, dbo.sysfilegroups g where g.groupid = @FGid and g.groupid = o.groupid and (o.status & 0x40) = 0
  3345.       fetch hC into @FGid
  3346.    end
  3347.     deallocate hC
  3348.  
  3349.    select * from #tempFG
  3350.    DROP TABLE #tempFG
  3351.  
  3352. go
  3353. /* End sp_MSscriptdb_worker */
  3354.  
  3355. /*******************************************************************************/
  3356. /*******************************************************************************/
  3357. /* exec sp_MSdbuseraccess 'perm', 'dbname' -- selecting priv bit from specified db                       */
  3358. /* exec sp_MSdbuseraccess 'db', 'dbname'   -- select databases, need to change db if dbname is specified */
  3359. /* exec sp_MSdbuseraccess 'init', 'dbname' -- noop                                                       */
  3360. /*******************************************************************************/
  3361. print N''
  3362. print N'Creating sp_MSdbuseraccess'
  3363. print N''
  3364. go
  3365.  
  3366. create proc sp_MSdbuseraccess
  3367.     @mode nvarchar(10) = N'perm', @qual nvarchar(128) = N'%'
  3368. as
  3369.    set deadlock_priority low
  3370.    
  3371.    create table #TmpDbUserProfile (
  3372.       dbid        int NOT NULL PRIMARY KEY,
  3373.       accessperms int NOT NULL
  3374.       )
  3375.  
  3376.    create table #TmpOut (
  3377.       name        nvarchar(132) NOT NULL,
  3378.       version     smallint,
  3379.       crdate      datetime,
  3380.       owner       nvarchar(132),
  3381.       dbid        smallint NOT NULL,
  3382.       status      int,
  3383.       category    int,
  3384.       status2     int,
  3385.       fulltext    int,
  3386.       )
  3387.  
  3388.    set nocount on
  3389.  
  3390.    declare @accessbit int
  3391.     if (lower(@mode) like N'perm%') begin
  3392.       /* verify */
  3393.       declare @id int, @stat int, @inval int
  3394.       select @id = dbid, @stat = status from master.dbo.sysdatabases where name = @qual
  3395.       if (@id is null) begin
  3396.          RAISERROR (15001, -1, -1, @qual)
  3397.          return 1
  3398.       end
  3399.  
  3400.       /* Can we access this db? */
  3401.       declare @single int
  3402.       select @single = DATABASEPROPERTY( @qual, N'issingleuser' )
  3403. /*      if ((@single <> 0) or ((@stat & SQLDMODBStat_Inaccessible) <> 0)) begin  */
  3404.       if ((@single <> 0) or
  3405.          (DATABASEPROPERTY(@qual, N'isdetached') <> 0) or
  3406.          (DATABASEPROPERTY(@qual, N'isshutdown') <> 0) or
  3407.          (DATABASEPROPERTY(@qual, N'issuspect') <> 0) or
  3408.          (DATABASEPROPERTY(@qual, N'isoffline') <> 0) or
  3409.          (DATABASEPROPERTY(@qual, N'isinload') <> 0) or
  3410.          (DATABASEPROPERTY(@qual, N'isinrecovery') <> 0) or
  3411.          (DATABASEPROPERTY(@qual, N'isnotrecovered') <> 0)) begin
  3412.          select @inval = 0x80000000
  3413.          select @inval
  3414.          return 0
  3415.       end
  3416.       select @accessbit = has_dbaccess(@qual)
  3417.       if ( @accessbit <> 1) begin
  3418.          select @inval = 0x40000000
  3419.          select @inval
  3420.          return 0
  3421.       end
  3422.  
  3423.       /** OK, we can access this db, need to go to the specified database to get priv bit **/
  3424.       declare @dbTempname nvarchar(258)
  3425.       declare @tempindex int
  3426.       SELECT @dbTempname = REPLACE(@qual, N']', N']]')
  3427.       exec (N'[' + @dbTempname + N']' + N'..sp_MSdbuserpriv ')
  3428.       return 0
  3429.    end
  3430.  
  3431.    /* If 'db', we want to know if what kind of access we have to the specified databases */
  3432.    /* If we are not in master, then we are selecting single database, we want to correct role bit to save round trip */
  3433.    if (lower(@mode) like N'db%') begin
  3434.       /* Make sure we're either in master or only doing it to current db. */
  3435.       declare @dbrole int
  3436.       select @dbrole = 0x0000
  3437.  
  3438.       if (db_id() <> 1)
  3439.          select @qual = db_name()
  3440.  
  3441.       /* If dbname contains ', double it for the cursor, since cursor statement is inside of '' */
  3442.       declare @qual2 nvarchar(517)
  3443.       SELECT @qual2 = REPLACE(@qual, N'''', N'''''')
  3444.  
  3445.       /* Preprocessor won't replace within quotes so have to use str(). */
  3446.       declare @invalidlogin nvarchar(12)
  3447.       select @invalidlogin = ltrim(str(convert(int, 0x40000000), 11))
  3448.       declare @inaccessible nvarchar(12)
  3449.       select @inaccessible = ltrim(str(convert(int, 0x80000000), 11))
  3450.  
  3451.       /* We can't 'use' a database with a version below the minimum. */
  3452.       /* SQL6.0 minimum is 406; SQL65 requires 408.  SQL70 database version is 408 now, it might change later */
  3453.       declare @mindbver smallint
  3454.       if (@@microsoftversion >= 0x07000000)
  3455.          select @mindbver = 408
  3456.       else
  3457.          select @mindbver = 406
  3458.  
  3459.       /* Select all matching databases -- we want an entry even for inaccessible ones. */
  3460.       declare @dbid smallint, @dbidstr nvarchar(12), @dbstat int, @dbname nvarchar(258), @dbver smallint
  3461.       declare @dbbits int, @dbbitstr nvarchar(12)
  3462.  
  3463.       /* !!! work around here, if name contains '[', LIKE operator can't find it, since LIKE operator it treating '[' as a wild char */
  3464.       /* !!! but @qual2 might be '%', then = operator does not work */
  3465.       declare @temp int
  3466.       select @tempindex = charindex(N'[', @qual2)
  3467.       if (@tempindex <> 0)
  3468.          exec(N'declare hCdbs cursor global for select name, dbid, status, version from master.dbo.sysdatabases where name = N''' + @qual2 + N'''')
  3469.       else
  3470.          exec(N'declare hCdbs cursor global for select name, dbid, status, version from master.dbo.sysdatabases where name like N''' + @qual2 + N'''')
  3471.  
  3472.       open hCdbs
  3473.  
  3474.       /* Loop for each database, and if it's accessible, recursively call ourselves to add it. */
  3475.       fetch hCdbs into @dbname, @dbid, @dbstat, @dbver
  3476.       while (@@fetch_status >= 0) begin
  3477.          /* Preprocessor won't replace within quotes so have to use str(). */
  3478.          select @dbidstr = ltrim(str(convert(int, @dbid)))
  3479.  
  3480.          /* If it's a single user db and there's an entry for it in sysprocesses who isn't us, we can't use it. */
  3481.          declare @single_lockedout int
  3482.          select @single_lockedout = DATABASEPROPERTY( @dbname, N'issingleuser' )
  3483.          if (@single_lockedout <> 0)
  3484.             select @single_lockedout = 0 where not exists
  3485.                (select * from master.dbo.sysprocesses p where dbid = @dbid and p.spid <> @@spid)
  3486.  
  3487.          /* First see if the db is accessible (not in load, recovery, offline, single-use with another user besides us, etc.) */
  3488. /*         if ((@single_lockedout <> 0) or ((@dbstat & SQLDMODBStat_Inaccessible) <> 0) or (@dbver < @mindbver)) begin   */
  3489.          if ((@single_lockedout <> 0) or
  3490.             (@dbver < @mindbver) or
  3491.             (DATABASEPROPERTY(@dbname, N'isdetached') <> 0) or
  3492.             (DATABASEPROPERTY(@dbname, N'isshutdown') <> 0) or
  3493.             (DATABASEPROPERTY(@dbname, N'issuspect') <> 0) or
  3494.             (DATABASEPROPERTY(@dbname, N'isoffline') <> 0) or
  3495.             (DATABASEPROPERTY(@dbname, N'isinload') <> 0) or
  3496.             (DATABASEPROPERTY(@dbname, N'isinrecovery') <> 0) or
  3497.             (DATABASEPROPERTY(@dbname, N'isnotrecovered') <> 0) ) begin
  3498.             /* Inaccessible, but we can set dbo if we're sa or suser_id() is db owner sid. */
  3499.             exec (N'insert #TmpDbUserProfile values (' + @dbidstr + N', ' + @inaccessible + N')')
  3500.             end
  3501.          else begin
  3502.             /* Find out whether the current user has access to the database */
  3503.             select @accessbit = has_dbaccess(@dbname)
  3504.             if ( @accessbit <> 1) begin
  3505.                exec (N'insert #TmpDbUserProfile values (' + @dbidstr + N', ' + @invalidlogin + N')')
  3506.                end
  3507.             else begin
  3508.                /* Yes, current user does have access to this database, we are not trying to get priv at this point */
  3509.                select @dbbits = 0x03ff
  3510.                select @dbbitstr = ltrim(convert(nvarchar(12), @dbbits))
  3511.                exec (N'insert #TmpDbUserProfile values (' + @dbidstr + N', ' + @dbbitstr + N')')
  3512.                end
  3513.             end
  3514.  
  3515.          fetch hCdbs into @dbname, @dbid, @dbstat, @dbver
  3516.       end /* while FETCH_SUCCESS */
  3517.       close hCdbs
  3518.       deallocate hCdbs
  3519.  
  3520.       /* Select sysdatabases info into temp table first to avoid deadlock in restore process */
  3521.       if (@tempindex <> 0)
  3522.          insert #TmpOut
  3523.          select o.name, o.version, o.crdate, suser_sname(o.sid), o.dbid, o.status, o.category, o.status2, DatabaseProperty(o.name, N'isfulltextenabled')
  3524.             from master.dbo.sysdatabases o where o.name = @qual
  3525.       else
  3526.          insert #TmpOut
  3527.          select o.name, o.version, o.crdate, suser_sname(o.sid), o.dbid, o.status, o.category, o.status2, DatabaseProperty(o.name, N'isfulltextenabled')
  3528.             from master.dbo.sysdatabases o where o.name like @qual
  3529.  
  3530.       /* 1. If on all databases, then dbrole is dummy, need to get it later */
  3531.       /* 2. Do not double the ' character(s) in database name */
  3532.       /* 3. To speed up connection, accessperms column only indicate whether the login user can access the db, it does not contain */
  3533.       /*    permission info, we will retrieve the permission info through sp_MSdbuserpriv when necessary */
  3534.       /* !!! work around here, if name contains '[', LIKE operator can't find it, since LIKE operator it treating '[' as a wild char */
  3535.       /* !!! but @qual2 might be '%', then = operator does not work */
  3536.       if (@tempindex <> 0)
  3537.          select o.name, o.version, o.crdate, o.owner, o.dbid, lSize = 0, NonDbo = 0, Status = o.status, spaceavail = 0,
  3538.             LogOnSepDev = 1, o.category, t.accessperms, @dbrole, o.fulltext, o.status2,
  3539.             collation = convert(sysname, databasepropertyex(o.name, N'collation'))
  3540.             from #TmpOut o left outer join #TmpDbUserProfile t on t.dbid = o.dbid where o.name = @qual order by o.name
  3541.       else
  3542.          select o.name, o.version, o.crdate, o.owner, o.dbid, lSize = 0, NonDbo = 0, Status = o.status, spaceavail = 0,
  3543.             LogOnSepDev = 1, o.category, t.accessperms, @dbrole, o.fulltext, o.status2,
  3544.             collation = convert(sysname, databasepropertyex(o.name, N'collation'))
  3545.             from #TmpOut o left outer join #TmpDbUserProfile t on t.dbid = o.dbid where o.name like @qual order by o.name
  3546.  
  3547.       DROP TABLE #TmpDbUserProfile
  3548.       DROP TABLE #TmpOut
  3549.       return 0
  3550.    end
  3551. go
  3552. /* End sp_MSdbuseraccess */
  3553.  
  3554.  
  3555. /*******************************************************************************/
  3556. /* exec sp_MSdbuserpriv 'serv'  -- selecting the server (master db) user profile, just create db priv, if sa, 7 */
  3557. /* exec sp_MSdbuserpriv 'role'  -- selecting role membership for current db                                     */
  3558. /* exec sp_MSdbuserpriv 'ver'   -- selectversion70                                                              */
  3559. /* exec sp_MSdbuserpriv 'perm'  -- selecting user priv bit for the current db                                   */
  3560. /*******************************************************************************/
  3561. print N''
  3562. print N'Creating sp_MSdbuserpriv'
  3563. print N''
  3564. go
  3565.  
  3566. create proc sp_MSdbuserpriv
  3567.     @mode nvarchar(10) = N'perm'
  3568. as
  3569.  
  3570. /* Order of privilege evaluation is:  user granted/revoked, then group granted/revoked, then public granted/revoked */
  3571.  
  3572.  
  3573.  
  3574.  
  3575.  
  3576.  
  3577.  
  3578.  
  3579.  
  3580.    set nocount on
  3581.    declare @bits int, @status int, @prot int, @perms int
  3582.    declare @dbrole int, @dbrolestr nvarchar(12)
  3583.  
  3584.    /* If 'srv', we're selecting the server (master db) user profile - currently, just create db priv. */
  3585.    if (lower(@mode) like N'serv%')
  3586.       begin
  3587.       select @bits = 0x0000
  3588.       if (user_id() = 1 or is_srvrolemember(N'sysadmin') = 1 or is_member(N'db_owner') = 1)
  3589.          begin
  3590.          /* sa has everything */
  3591.          select @bits = 0x0007
  3592.          end
  3593.       else begin
  3594.          if ((PERMISSIONS() & 1) > 0)
  3595.             SELECT @bits = @bits | 0x0002
  3596.          if ((PERMISSIONS(OBJECT_ID(N'sp_addextendedproc')) & 32) > 0)
  3597.             SELECT @bits = @bits | 0x0004
  3598.          end
  3599.       select @bits
  3600.       return 0
  3601.       end
  3602.  
  3603.    /* If 'perm', we're selecting the current database priv and role membership for the login user. */
  3604.     if (lower(@mode) like N'role%' or lower(@mode) like N'ver%' or lower(@mode) like N'perm%')
  3605.       begin
  3606.       if (user_id() = 1 or is_srvrolemember(N'sysadmin') = 1 or is_member(N'db_owner') = 1)
  3607.          begin
  3608.          /* sa/Dbo has everything. */
  3609.          select @bits = 0x03ff
  3610.          end
  3611.       else begin
  3612.          /* Not dbo so get individual privileges */
  3613.          select @bits = 0x0000, @perms = PERMISSIONS(), @status = status from dbo.sysusers where uid = user_id()
  3614.  
  3615.          if ((@perms & 2) > 0)
  3616.             SELECT @bits = @bits | 0x0002
  3617.          if ((@perms & 8) > 0)
  3618.             SELECT @bits = @bits | 0x0004
  3619.          if ((@perms & 4) > 0)
  3620.             SELECT @bits = @bits | 0x0008
  3621.          if ((@perms & 64) > 0)
  3622.             SELECT @bits = @bits | 0x0010
  3623.          if ((@perms & 32) > 0)
  3624.             SELECT @bits = @bits | 0x0020
  3625.          if ((@perms & 128) > 0)
  3626.             SELECT @bits = @bits | 0x0040
  3627.          if ((@perms & 16) > 0)
  3628.             SELECT @bits = @bits | 0x0080
  3629.          if ((@perms & 256) > 0)
  3630.             SELECT @bits = @bits | 0x0100
  3631.          if ((@perms & 512) > 0)
  3632.             SELECT @bits = @bits | 0x0200
  3633.          end
  3634.  
  3635.       /* Get both Server and Database Role information */
  3636.       select @dbrole = 0x0000
  3637.       /* Server Roles */
  3638.       select @dbrole = (case when (is_srvrolemember(N'dbcreator') = 1) then @dbrole | 0x0001 else @dbrole end),
  3639.              @dbrole = (case when (is_srvrolemember(N'diskadmin') = 1) then @dbrole | 0x0002 else @dbrole end),
  3640.              @dbrole = (case when (is_srvrolemember(N'processadmin') = 1) then @dbrole | 0x0004 else @dbrole end),
  3641.              @dbrole = (case when (is_srvrolemember(N'securityadmin') = 1) then @dbrole | 0x0008 else @dbrole end),
  3642.              @dbrole = (case when (is_srvrolemember(N'serveradmin') = 1) then @dbrole | 0x0010 else @dbrole end),
  3643.              @dbrole = (case when (is_srvrolemember(N'setupadmin') = 1) then @dbrole | 0x0020 else @dbrole end),
  3644.              @dbrole = (case when (is_srvrolemember(N'sysadmin') = 1) then @dbrole | 0x0040 else @dbrole end),
  3645.              @dbrole = (case when (is_srvrolemember(N'bulkadmin') = 1) then @dbrole | 0x10000 else @dbrole end),
  3646.       /* Database Roles */
  3647.              @dbrole = (case when (is_member(N'db_accessadmin') = 1) then @dbrole | 0x0080 else @dbrole end),
  3648.              @dbrole = (case when (is_member(N'db_datareader') = 1) then @dbrole | 0x0100 else @dbrole end),
  3649.              @dbrole = (case when (is_member(N'db_ddladmin') = 1) then @dbrole | 0x0200 else @dbrole end),
  3650.              @dbrole = (case when (is_member(N'db_denydatareader') = 1) then @dbrole | 0x0400 else @dbrole end),
  3651.              @dbrole = (case when (is_member(N'db_denydatawriter') = 1) then @dbrole | 0x0800 else @dbrole end),
  3652.              @dbrole = (case when (is_member(N'db_backupoperator') = 1) then @dbrole | 0x1000 else @dbrole end),
  3653.              @dbrole = (case when (is_member(N'db_owner') = 1) then @dbrole | 0x2000 else @dbrole end),
  3654.              @dbrole = (case when (is_member(N'db_securityadmin') = 1) then @dbrole | 0x4000 else @dbrole end),
  3655.              @dbrole = (case when (is_member(N'db_datawriter') = 1) then @dbrole | 0x8000 else @dbrole end)
  3656.  
  3657.       if (lower(@mode) like N'ver%')
  3658.          begin
  3659. /* 7.0
  3660.          select @@version, N'login_id' = convert(int, suser_sid()), N'pagesize' = v.low, N'highbit' = v2.low, N'highbyte' = v3.low,
  3661.             N'casesens' = (case when (N'A' != N'a') then 1 else 0 end), @@spid, @@servername, is_srvrolemember(N'sysadmin'), @dbrole
  3662.             from master..spt_values v,master..spt_values v2,master..spt_values v3 where v.number=1 and v.type=N'E' and v2.number=2
  3663.             and v2.type=N'E' and v3.number=3 and v3.type=N'E'
  3664. */
  3665.          select @@version, N'login_id' = convert(int, suser_sid()), N'pagesize' = v.low, N'highbit' = v2.low, N'highbyte' = v3.low,
  3666.             N'casesens' = (case when (N'A' != N'a') then 1 else 0 end), @@spid, convert(sysname, serverproperty(N'servername')),
  3667.             is_srvrolemember(N'sysadmin'), @dbrole,
  3668.             N'InstanceName' = convert(sysname, serverproperty(N'instancename')),
  3669.             N'PID' = convert(int, serverproperty(N'processid'))
  3670.             from master..spt_values v,master..spt_values v2,master..spt_values v3 where v.number=1 and v.type=N'E' and v2.number=2
  3671.             and v2.type=N'E' and v3.number=3 and v3.type=N'E'
  3672.          end
  3673.       else if (lower(@mode) like N'role%')
  3674.          begin
  3675.          select @dbrole
  3676.          end
  3677.       else if (lower(@mode) like N'perm%')
  3678.          begin
  3679.          select @bits
  3680.          end
  3681.       return 0
  3682.       end
  3683. go
  3684. /* End sp_MSdbuserpriv */
  3685.  
  3686.  
  3687. /*******************************************************************************/
  3688. print N''
  3689. print N'Creating sp_MShelpfulltextindex'
  3690. print N''
  3691. go
  3692.  
  3693. create proc sp_MShelpfulltextindex
  3694.    @tablename nvarchar(517)
  3695. as
  3696.  
  3697.     create table #sphelpft
  3698.       (
  3699.          ind_name   nvarchar(128) COLLATE database_default NOT NULL,
  3700.       col1       nvarchar(128) COLLATE database_default,
  3701.       col2       nvarchar(128) COLLATE database_default,
  3702.       col3       nvarchar(128) COLLATE database_default,
  3703.       col4       nvarchar(128) COLLATE database_default,
  3704.       col5       nvarchar(128) COLLATE database_default,
  3705.       col6       nvarchar(128) COLLATE database_default,
  3706.       col7       nvarchar(128) COLLATE database_default,
  3707.       col8       nvarchar(128) COLLATE database_default,
  3708.       col9       nvarchar(128) COLLATE database_default,
  3709.       col10      nvarchar(128) COLLATE database_default,
  3710.       col11      nvarchar(128) COLLATE database_default,
  3711.       col12      nvarchar(128) COLLATE database_default,
  3712.       col13      nvarchar(128) COLLATE database_default,
  3713.       col14      nvarchar(128) COLLATE database_default,
  3714.       col15      nvarchar(128) COLLATE database_default,
  3715.       col16      nvarchar(128) COLLATE database_default
  3716.       )
  3717.  
  3718.    set nocount on
  3719.  
  3720.    /* all the possible full text unique indexes */
  3721.    declare @objid int
  3722.    select @objid = object_id(@tablename, N'local')
  3723.       insert #sphelpft
  3724.          select i.name,
  3725.          columnproperty( @objid, index_col(@tablename, i.indid, 1), N'AllowsNull'),
  3726.          columnproperty( @objid, index_col(@tablename, i.indid, 2), N'AllowsNull'),
  3727.          columnproperty( @objid, index_col(@tablename, i.indid, 3), N'AllowsNull'),
  3728.          columnproperty( @objid, index_col(@tablename, i.indid, 4), N'AllowsNull'),
  3729.          columnproperty( @objid, index_col(@tablename, i.indid, 5), N'AllowsNull'),
  3730.          columnproperty( @objid, index_col(@tablename, i.indid, 6), N'AllowsNull'),
  3731.          columnproperty( @objid, index_col(@tablename, i.indid, 7), N'AllowsNull'),
  3732.          columnproperty( @objid, index_col(@tablename, i.indid, 8), N'AllowsNull'),
  3733.          columnproperty( @objid, index_col(@tablename, i.indid, 9), N'AllowsNull'),
  3734.          columnproperty( @objid, index_col(@tablename, i.indid, 10), N'AllowsNull'),
  3735.          columnproperty( @objid, index_col(@tablename, i.indid, 11), N'AllowsNull'),
  3736.          columnproperty( @objid, index_col(@tablename, i.indid, 12), N'AllowsNull'),
  3737.          columnproperty( @objid, index_col(@tablename, i.indid, 13), N'AllowsNull'),
  3738.          columnproperty( @objid, index_col(@tablename, i.indid, 14), N'AllowsNull'),
  3739.          columnproperty( @objid, index_col(@tablename, i.indid, 15), N'AllowsNull'),
  3740.          columnproperty( @objid, index_col(@tablename, i.indid, 16), N'AllowsNull')
  3741.          from dbo.sysindexes i where
  3742.          @objid = i.id and
  3743.          IndexProperty(@objid, i.name, N'IsUnique') = 1 and
  3744.          IndexProperty(@objid, i.name, N'UserKeyCount') = 1 and
  3745.          /* 450 byte MAX */
  3746.          exists (select * from dbo.syscolumns where id = @objid and name = Index_col(@tablename, IndexProperty(@objid, i.name, N'IndexId'), 1)
  3747.                  and length <= 450)
  3748.  
  3749.    /* Now we need to filter out the indexes which the associated key(s) are nullable */
  3750.    /* Each index can have up to 16 associated keys, all of them need to be non-nullalbe for the index to be qualified as a full text index */
  3751.    delete #sphelpft where col1 = 1 or col2 = 1 or col3 = 1 or col4 = 1 or col5 = 1 or col6 = 1 or col7 = 1 or col8 = 1 or
  3752.                           col9 = 1 or col10 = 1 or col11 = 1 or col12 = 1 or col13 = 1 or col14 = 1 or col15 = 1 or col16 = 1
  3753.  
  3754.    select ind_name from #sphelpft
  3755.    DROP TABLE #sphelpft
  3756.  
  3757. go
  3758. /* End sp_MShelpfulltextindex */
  3759.  
  3760. /*******************************************************************************/
  3761. print N''
  3762. print N'Creating sp_MShelpfulltextscript'
  3763. print N''
  3764. go
  3765.  
  3766. create proc sp_MShelpfulltextscript
  3767.    @tablename nvarchar(517)
  3768. as
  3769.    set nocount on
  3770.  
  3771.     declare @objid int
  3772.     select @objid = object_id(@tablename)
  3773.     if (@objid is null)
  3774.     begin
  3775.         RAISERROR (15001, -1, -1, @tablename)
  3776.         return 1
  3777.     end
  3778.  
  3779.    /* prepare the information for fulltext index scripting */
  3780.    declare @activate    int
  3781.    select @activate = OBJECTPROPERTY(@objid, N'TableFulltextCatalogId')
  3782.     if (@activate <> 0)
  3783.       begin
  3784.       declare @uniqueindex nvarchar(128)
  3785.       declare @catname     nvarchar(128)
  3786.  
  3787.       /* get unique index name */
  3788.       select @uniqueindex = i.name from dbo.sysindexes i where @objid = i.id and IndexProperty(@objid, i.name, N'IsFulltextKey') = 1
  3789.       /* get catalog name */
  3790.       select @catname = f.name from dbo.sysfulltextcatalogs f, dbo.sysobjects o where f.ftcatid = o.ftcatid and o.id = @objid
  3791.       if (@uniqueindex is not null and @catname is not null)
  3792.          begin
  3793.          /* is this table fulltext index activated? */
  3794.          select @activate = OBJECTPROPERTY(@objid, N'TableHasActiveFulltextIndex')
  3795.          select @uniqueindex, @catname, @activate
  3796.          end
  3797.       end
  3798.  
  3799. go
  3800. /* End sp_MShelpfulltextscript */
  3801.  
  3802. /*******************************************************************************/
  3803. print N''
  3804. print N'Creating sp_MSSetServerProperties'
  3805. print N''
  3806. go
  3807.  
  3808. create proc sp_MSSetServerProperties
  3809.    @auto_start    INT   = NULL   -- 1 or 0, while 1 = auto start, 0 = manual start
  3810. as
  3811.    set nocount on
  3812.  
  3813.    -- only sysadmins are allowed to execute this stored procedure
  3814.    if( is_srvrolemember(N'sysadmin') = 0 )
  3815.        begin
  3816.        RAISERROR (15003, -1, -1, N'sysadmin')
  3817.        return 1
  3818.        end
  3819.  
  3820.    -- Make sure values (if supplied) are good
  3821.    IF (@auto_start IS NOT NULL)
  3822.    BEGIN
  3823.       -- NOTE: When setting the the services start value, 2 == auto-start, 3 == Don't auto-start
  3824.       SELECT @auto_start = CASE @auto_start
  3825.                            WHEN 0 THEN 3
  3826.                            WHEN 1 THEN 2
  3827.                            ELSE 3 -- Assume non auto-start if passed a junk value
  3828.                            END
  3829.    END
  3830.  
  3831.    -- Write out the values
  3832.    IF (@auto_start IS NOT NULL)
  3833.    BEGIN
  3834.       IF ((PLATFORM() & 0x1) = 0x1) -- NT
  3835.          EXECUTE master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  3836.                                                  N'SYSTEM\CurrentControlSet\Services\MSSQLServer',
  3837.                                                  N'Start',
  3838.                                                  N'REG_DWORD',
  3839.                                                  @auto_start
  3840.       ELSE
  3841.          RAISERROR(14546, 16, 1, '@auto_start')
  3842.    END
  3843.  
  3844. go
  3845. /* End sp_MSSetServerProperties */
  3846.  
  3847. /*******************************************************************************/
  3848. print N''
  3849. print N'Creating sp_MSGetServerProperties'
  3850. print N''
  3851. go
  3852.  
  3853. create proc sp_MSGetServerProperties
  3854. as
  3855.    set nocount on
  3856.  
  3857.    DECLARE @auto_start                  INT
  3858.    DECLARE @startup_account             NVARCHAR(100)
  3859.  
  3860.    -- Read the values from the registry
  3861.    IF ((PLATFORM() & 0x1) = 0x1) -- NT
  3862.    BEGIN
  3863.       EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  3864.                                              N'SYSTEM\CurrentControlSet\Services\MSSQLServer',
  3865.                                              N'Start',
  3866.                                              @auto_start OUTPUT,
  3867.                                              N'no_output'
  3868.       EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  3869.                                              N'SYSTEM\CurrentControlSet\Services\MSSQLServer',
  3870.                                              N'ObjectName',
  3871.                                              @startup_account OUTPUT,
  3872.                                              N'no_output'
  3873.    END ELSE
  3874.    BEGIN
  3875.       SELECT @auto_start = 3 -- Manual start
  3876.       SELECT @startup_account = NULL
  3877.    END
  3878.  
  3879.    -- Return the values to the client
  3880.    SELECT auto_start = CASE @auto_start
  3881.                        WHEN 2 THEN 1 -- 2 means auto-start
  3882.                        WHEN 3 THEN 0 -- 3 means don't auto-start
  3883.                        ELSE 0        -- Safety net
  3884.                        END,
  3885.           startup_account = @startup_account
  3886.  
  3887. go
  3888. /* End sp_MSGetServerProperties */
  3889.  
  3890.  
  3891. /*******************************************************************************/
  3892. print N''
  3893. print N'Creating fn_MSFullText'
  3894. print N''
  3895. go
  3896.  
  3897. create function fn_MSFullText()
  3898. returns @retTab table(LCID int)
  3899. as
  3900. begin
  3901.    declare @tempLang table(LCID int)
  3902.    insert @tempLang values (2052)  /* Chinese_Simplified */
  3903.    insert @tempLang values (1028)  /* Chinese_Traditional */
  3904.    insert @tempLang values (1043)  /* Dutch */
  3905.    insert @tempLang values (2057)  /* English_UK */
  3906.    insert @tempLang values (1033)  /* English_US */
  3907.    insert @tempLang values (1036)  /* French */
  3908.    insert @tempLang values (1031)  /* German */
  3909.    insert @tempLang values (1040)  /* Italian */
  3910.    insert @tempLang values (1041)  /* Japanese */
  3911.    insert @tempLang values (1042)  /* Korean */
  3912.    insert @tempLang values (0)     /* Neutral */
  3913.    insert @tempLang values (1053)  /* Swedish_Default */
  3914.  
  3915.    insert @retTab select * from @tempLang
  3916. return
  3917. end
  3918. go
  3919. /* End fn_MSFullText */
  3920.  
  3921.  
  3922. /*******************************************************************************/
  3923. print N''
  3924. print N'Creating sp_MSSharedFixedDisk'
  3925. print N''
  3926. go
  3927.  
  3928. create proc sp_MSSharedFixedDisk
  3929. as
  3930.    set nocount on
  3931.  
  3932.    create table #Tmp1
  3933.       (
  3934.       name         nvarchar(132),
  3935.       low          int,
  3936.       high         int,
  3937.       media        int,
  3938.       )
  3939.    create table #Tmp2
  3940.       (
  3941.       drivename    nvarchar(132),
  3942.       )
  3943.    declare @DriveName nvarchar(132)
  3944.  
  3945.    declare hC cursor global for select * from ::fn_servershareddrives()
  3946.    open hC
  3947.    fetch next from hC into @DriveName
  3948.    while (@@FETCH_STATUS = 0)
  3949.       begin
  3950.       insert #Tmp2 select @DriveName
  3951.       fetch next from hC into @DriveName
  3952.       end
  3953.    close hC
  3954.    deallocate hC
  3955.  
  3956.    insert into #Tmp1
  3957.    execute master.dbo.xp_availablemedia 15
  3958.  
  3959.    select 'name' = name, 'low free' = low, 'high free' = high, 'media type' = media from #Tmp1, #Tmp2
  3960.           where (SUBSTRING(#Tmp1.name, 1, 1)) like (SUBSTRING(#Tmp2.drivename, 1, 1))
  3961.  
  3962. go
  3963. /* End sp_MSSharedFixedDisk */
  3964.  
  3965.  
  3966. /********************* Grant privileges *********************************/
  3967. print N''
  3968. print N'Granting execute permissions on procedures'
  3969. print N''
  3970. go
  3971.  
  3972. /**  Mark all the SPs as system objects **/
  3973. exec sp_MS_marksystemobject sp_MShelpcolumns
  3974. go
  3975. exec sp_MS_marksystemobject sp_MShelpindex
  3976. go
  3977. exec sp_MS_marksystemobject sp_MShelptype
  3978. go
  3979. exec sp_MS_marksystemobject sp_MSdependencies
  3980. go
  3981. exec sp_MS_marksystemobject sp_MStablespace
  3982. go
  3983. exec sp_MS_marksystemobject sp_MSindexspace
  3984. go
  3985. exec sp_MS_marksystemobject sp_MStablerefs
  3986. go
  3987. exec sp_MS_marksystemobject sp_MStablekeys
  3988. go
  3989. exec sp_MS_marksystemobject sp_MStablechecks
  3990. go
  3991. exec sp_MS_marksystemobject sp_MSsettopology
  3992. go
  3993. exec sp_MS_marksystemobject sp_MSmatchkey
  3994. go
  3995. exec sp_MS_marksystemobject sp_MSforeach_worker
  3996. go
  3997. exec sp_MS_marksystemobject sp_MSforeachdb
  3998. go
  3999. exec sp_MS_marksystemobject sp_MSforeachtable
  4000. go
  4001. exec sp_MS_marksystemobject sp_MSloginmappings
  4002. go
  4003. exec sp_MS_marksystemobject sp_MSuniquename
  4004. go
  4005. exec sp_MS_marksystemobject sp_MSkilldb
  4006. go
  4007. exec sp_MS_marksystemobject sp_MSobjectprivs
  4008. go
  4009. exec sp_MS_marksystemobject sp_MSSQLDMO80_version
  4010. go
  4011. exec sp_MS_marksystemobject sp_MSSQLDMO70_version
  4012. go
  4013. exec sp_MS_marksystemobject sp_MSSQLOLE65_version
  4014. go
  4015. exec sp_MS_marksystemobject sp_MSSQLOLE_version
  4016. go
  4017. exec sp_MS_marksystemobject sp_MSscriptdatabase
  4018. go
  4019. exec sp_MS_marksystemobject sp_MSscriptdb_worker
  4020. go
  4021. exec sp_MS_marksystemobject sp_MSdbuseraccess
  4022. go
  4023. exec sp_MS_marksystemobject sp_MSdbuserpriv
  4024. go
  4025. exec sp_MS_marksystemobject sp_MShelpfulltextindex
  4026. go
  4027. exec sp_MS_marksystemobject sp_MShelpfulltextscript
  4028. go
  4029. exec sp_MS_marksystemobject sp_MSSetServerProperties
  4030. go
  4031. exec sp_MS_marksystemobject sp_MSGetServerProperties
  4032. go
  4033. exec sp_MS_marksystemobject fn_MSFullText
  4034. go
  4035. exec sp_MS_marksystemobject sp_MSSharedFixedDisk
  4036. go
  4037.  
  4038. grant execute on sp_MShelpcolumns to public
  4039. grant execute on sp_MShelpindex to public
  4040. grant execute on sp_MShelptype to public
  4041. grant execute on sp_MSdependencies to public
  4042. grant execute on sp_MStablespace to public
  4043. grant execute on sp_MSindexspace to public
  4044. grant execute on sp_MSuniquename to public
  4045. grant execute on sp_MSkilldb to public
  4046. grant execute on sp_MSobjectprivs to public
  4047. grant execute on sp_MSloginmappings to public
  4048. grant execute on sp_MStablekeys to public
  4049. grant execute on sp_MStablechecks to public
  4050. grant execute on sp_MStablerefs to public
  4051. grant execute on sp_MSsettopology to public
  4052. grant execute on sp_MSmatchkey to public
  4053. grant execute on sp_MSforeachdb to public
  4054. grant execute on sp_MSforeachtable to public
  4055. grant execute on sp_MSforeach_worker to public
  4056. grant execute on sp_MSSQLOLE_version to public
  4057. grant execute on sp_MSSQLOLE65_version to public
  4058. grant execute on sp_MSSQLDMO70_version to public
  4059. grant execute on sp_MSSQLDMO80_version to public
  4060. grant execute on sp_MSscriptdatabase to public
  4061. grant execute on sp_MSscriptdb_worker to public
  4062. grant execute on sp_MSdbuseraccess to public
  4063. grant execute on sp_MSdbuserpriv to public
  4064. grant execute on sp_MShelpfulltextindex to public
  4065. grant execute on sp_MShelpfulltextscript to public
  4066. grant execute on sp_MSGetServerProperties to public
  4067. grant select  on fn_MSFullText to public
  4068. grant execute on sp_MSSharedFixedDisk to public
  4069.  
  4070. go
  4071.  
  4072.  
  4073.  
  4074.  
  4075.  
  4076.  
  4077.  
  4078.  
  4079.  
  4080.  
  4081.  
  4082.  
  4083.  
  4084.  
  4085.  
  4086.  
  4087.  
  4088. /********************* Delete existing objects *********************************/
  4089. print ''
  4090. print 'Deleting existing objects...'
  4091. print ''
  4092. go
  4093.  
  4094. if exists (select * from master..sysobjects where sysstat & 0x0f = 4 and name = 'sp_MSfilterclause')
  4095.     drop procedure sp_MSfilterclause
  4096. go
  4097.  
  4098. /********************* Create new objects *********************************/
  4099.  
  4100. print ''
  4101. print 'Creating sp_MSfilterclause'
  4102. print ''
  4103. go
  4104.  
  4105. create procedure sp_MSfilterclause
  4106.     @publication nvarchar(258), @article nvarchar(258)
  4107. as
  4108.     /* Return a text column as multiple readtexts of maxcol length */
  4109.     declare @pubid int, @artid int
  4110.     select @pubid = pubid from syspublications where name = @publication
  4111.     if (@pubid is null) begin
  4112.         RAISERROR (15001, 11, -1, @publication)
  4113.         return 1
  4114.     end
  4115.     select @artid = artid from sysarticles where name = @article and pubid = @pubid
  4116.     if (@artid is null) begin
  4117.         RAISERROR (15001, 11, -1, @article)
  4118.         return 1
  4119.     end
  4120.  
  4121.     declare @val varbinary(16), @len int, @ii int, @chunk int
  4122.     -- filter clause is in unicode, the length is a half of the number of bytes.
  4123.     select @val = textptr(filter_clause), @len = datalength(filter_clause)/2 from sysarticles where artid = @artid and pubid = @pubid
  4124.     select @ii = 0, @chunk = 255
  4125.  
  4126.     /* Get all the rows of an maxcol size */
  4127.     while @len > @chunk begin
  4128.         readtext sysarticles.filter_clause @val @ii @chunk
  4129.         select @ii = @ii + @chunk, @len = @len - @chunk
  4130.     end
  4131.  
  4132.     /* Get the last chunk */
  4133.     if (@len > 0)
  4134.         readtext sysarticles.filter_clause @val @ii @len
  4135.     return 0
  4136. go
  4137. /* End sp_MSfilterclause */
  4138.  
  4139. /*-----------------------------------------------------*/
  4140. /*-----------------------------------------------------*/
  4141.  
  4142. /********************* Grant privileges *********************************/
  4143. print ''
  4144. print 'Granting execute permissions on procedures'
  4145. print ''
  4146. go
  4147.  
  4148. exec sp_MS_marksystemobject sp_MSfilterclause
  4149. go
  4150.  
  4151. grant execute on sp_MSfilterclause to public
  4152.  
  4153.  
  4154.  
  4155.  
  4156.  
  4157.  
  4158.  
  4159.  
  4160.  
  4161.  
  4162.  
  4163.  
  4164.  
  4165.  
  4166. /********************* Delete existing objects *********************************/
  4167. print N''
  4168. print N'Deleting existing objects...'
  4169. print N''
  4170. go
  4171.  
  4172. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = 'sp_MSgetalertinfo')
  4173.     drop procedure sp_MSgetalertinfo
  4174. go
  4175. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = 'sp_MSsetalertinfo')
  4176.     drop procedure sp_MSsetalertinfo
  4177. go
  4178.  
  4179. /********************* Create new objects *********************************/
  4180.  
  4181. print N''
  4182. print N'Creating sp_MSgetalertinfo'
  4183. print N''
  4184. go
  4185. create procedure sp_MSgetalertinfo
  4186.     @includeaddresses bit = 0
  4187. as
  4188.     /* Return all alert info at one go, for performance reasons. */
  4189.     declare @FailSafeOperator nvarchar(255)
  4190.     declare @NotificationMethod int
  4191.     declare @ForwardingServer nvarchar(255)
  4192.     declare @ForwardingSeverity int
  4193.     declare @ForwardAlways int
  4194.     declare @PagerToTemplate nvarchar(255)
  4195.     declare @PagerCCTemplate nvarchar(255)
  4196.     declare @PagerSubjectTemplate nvarchar(255)
  4197.     declare @PagerSendSubjectOnly int
  4198.     declare @FailSafeEmailAddress nvarchar(255)
  4199.     declare @FailSafePagerAddress nvarchar(255)
  4200.     declare @FailSafeNetSendAddress nvarchar(255)
  4201.  
  4202.     exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertFailSafeOperator', @param = @FailSafeOperator OUT, @no_output = N'no_output'
  4203.     exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertNotificationMethod', @param = @NotificationMethod OUT, @no_output = N'no_output'
  4204.     exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertForwardingServer', @param = @ForwardingServer OUT, @no_output = N'no_output'
  4205.     exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertForwardingSeverity', @param = @ForwardingSeverity OUT, @no_output = N'no_output'
  4206.     exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertForwardAlways', @param = @ForwardAlways OUT, @no_output = N'no_output'
  4207.     exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertPagerToTemplate', @param = @PagerToTemplate OUT, @no_output = N'no_output'
  4208.     exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertPagerCCTemplate', @param = @PagerCCTemplate OUT, @no_output = N'no_output'
  4209.     exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertPagerSubjectTemplate', @param = @PagerSubjectTemplate OUT, @no_output = N'no_output'
  4210.     exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertPagerSendSubjectOnly', @param = @PagerSendSubjectOnly OUT, @no_output = N'no_output'
  4211.  
  4212.     if (@includeaddresses <> 0) begin
  4213.         exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertFailSafeEmailAddress', @param = @FailSafeEmailAddress OUT, @no_output = N'no_output'
  4214.         exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertFailSafePagerAddress', @param = @FailSafePagerAddress OUT, @no_output = N'no_output'
  4215.         exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertFailSafeNetSendAddress', @param = @FailSafeNetSendAddress OUT, @no_output = N'no_output'
  4216.     end
  4217.  
  4218.     select
  4219.         AlertFailSafeOperator = @FailSafeOperator,
  4220.         AlertNotificationMethod = @NotificationMethod,
  4221.         AlertForwardingServer = @ForwardingServer,
  4222.         AlertForwardingSeverity = @ForwardingSeverity,
  4223.         AlertPagerToTemplate = @PagerToTemplate,
  4224.         AlertPagerCCTemplate = @PagerCCTemplate,
  4225.         AlertPagerSubjectTemplate = @PagerSubjectTemplate,
  4226.         AlertPagerSendSubjectOnly = @PagerSendSubjectOnly,
  4227.         AlertForwardAlways = ISNULL(@ForwardAlways, 0)
  4228.  
  4229.     if (@includeaddresses <> 0)
  4230.         select
  4231.             AlertFailSafeEmailAddress = @FailSafeEmailAddress,
  4232.             AlertFailSafePagerAddress = @FailSafePagerAddress,
  4233.             AlertFailSafeNetSendAddress = @FailSafeNetSendAddress
  4234. go
  4235. /* End sp_MSgetalertinfo */
  4236.  
  4237. /*-----------------------------------------------------*/
  4238. /*-----------------------------------------------------*/
  4239. print N''
  4240. print N'Creating sp_MSsetalertinfo'
  4241. print N''
  4242. go
  4243. create procedure sp_MSsetalertinfo
  4244.     @failsafeoperator nvarchar(255) = null,
  4245.     @notificationmethod int = null,
  4246.     @forwardingserver nvarchar(255) = null,
  4247.     @forwardingseverity int = null,
  4248.     @pagertotemplate nvarchar(255) = null,
  4249.     @pagercctemplate nvarchar(255) = null,
  4250.     @pagersubjecttemplate nvarchar(255) = null,
  4251.     @pagersendsubjectonly int = null,
  4252.     @failsafeemailaddress nvarchar(255) = null,
  4253.     @failsafepageraddress nvarchar(255) = null,
  4254.     @failsafenetsendaddress nvarchar(255) = null,
  4255.     @forwardalways int = null -- 0 = forward only unhandled events, 1 = always forward events (both subject to @forwardingseverity)
  4256. as
  4257.  
  4258.    -- only sysadmins are allowed to execute this stored procedure
  4259.    if( is_srvrolemember(N'sysadmin') = 0 )
  4260.        begin
  4261.        RAISERROR (15003, -1, -1, N'sysadmin')
  4262.        return 1
  4263.        end
  4264.  
  4265.     /* Set all alert info at one go, for performance reasons.  Translate values if needed. */
  4266.     if (@pagersendsubjectonly is not null and @pagersendsubjectonly <> 0)
  4267.         select @pagersendsubjectonly = 1
  4268.  
  4269.     if (@failsafeoperator is not null)
  4270.         exec master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertFailSafeOperator', N'REG_SZ', @failsafeoperator
  4271.     if (@notificationmethod is not null)
  4272.         exec master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertNotificationMethod', N'REG_DWORD', @notificationmethod
  4273.     if (@forwardingserver is not null)
  4274.         exec master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertForwardingServer', N'REG_SZ', @forwardingserver
  4275.     if (@forwardingseverity is not null)
  4276.         exec master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertForwardingSeverity', N'REG_DWORD', @forwardingseverity
  4277.     if (@pagertotemplate is not null)
  4278.         exec master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertPagerToTemplate', N'REG_SZ', @pagertotemplate
  4279.     if (@pagercctemplate is not null)
  4280.         exec master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertPagerCCTemplate', N'REG_SZ', @pagercctemplate
  4281.     if (@pagersubjecttemplate is not null)
  4282.         exec master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertPagerSubjectTemplate', N'REG_SZ', @pagersubjecttemplate
  4283.     if (@pagersendsubjectonly is not null)
  4284.         exec master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertPagerSendSubjectOnly', N'REG_DWORD', @pagersendsubjectonly
  4285.     if (@failsafeemailaddress is not null)
  4286.         exec master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertFailSafeEmailAddress', N'REG_SZ', @failsafeemailaddress
  4287.     if (@failsafepageraddress is not null)
  4288.         exec master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertFailSafePagerAddress', N'REG_SZ', @failsafepageraddress
  4289.     if (@failsafenetsendaddress is not null)
  4290.         exec master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertFailSafeNetSendAddress', N'REG_SZ', @failsafenetsendaddress
  4291.     if (@forwardalways is not null)
  4292.         exec master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertForwardAlways', N'REG_DWORD', @forwardalways
  4293. go
  4294. /* End sp_MSgetalertinfo */
  4295.  
  4296. /********************* Grant privileges *********************************/
  4297. print N''
  4298. print N'Granting execute permissions on procedures'
  4299. print N''
  4300. go
  4301.  
  4302. exec sp_MS_marksystemobject sp_MSgetalertinfo
  4303. go
  4304. exec sp_MS_marksystemobject sp_MSsetalertinfo
  4305. go
  4306.  
  4307. grant execute on sp_MSgetalertinfo to public
  4308.  
  4309.  
  4310. /********************** Verify object creation and update category bit for objects *********************************/
  4311.  
  4312.  
  4313.  
  4314.  
  4315.  
  4316. print ''
  4317. print 'Updating category for objects created by SQLDMO70.sql.'
  4318. print ''
  4319. go
  4320.  
  4321. sp_configure 'allow updates', 1
  4322. go
  4323. reconfigure with override
  4324. go
  4325.  
  4326. /* if (@@microsoftversion >= SQL70_MINVERSION) begin                                      */
  4327. /*     exec sp_MS_upd_sysobj_category 2                                                    */
  4328. /* end else begin                                                                         */
  4329. /*     RAISERROR 55555 'You need a released version of SQL 8.0 to run this SQLDMO script'  */
  4330. /* end                                                                                    */
  4331. if (@@microsoftversion < 0x08000000) begin
  4332.     RAISERROR 55555 'You need a released version of SQL 8.0 to run this SQLDMO script'
  4333. end
  4334. go
  4335.  
  4336. sp_configure 'allow updates', 0
  4337. go
  4338. reconfigure with override
  4339. go
  4340.  
  4341. if (object_id('sp_MSSQLDMO80_version') is not null) begin
  4342.     print ''
  4343.     print ''
  4344.     print ' Successful installation.'
  4345.     exec sp_MSSQLDMO80_version
  4346. end
  4347.  
  4348. /************* DUMP THE TRANSACTION LOG **************************************/
  4349. /* Comment this out if you don't want your log dumped.  If you rerun this    */
  4350. /* script periodically, you will run out of transaction log space.           */
  4351. print ''
  4352. print 'Dumping transaction log...'
  4353. print ''
  4354. go
  4355. dump tran master with no_log
  4356. go
  4357. checkpoint
  4358. go
  4359. /************* END DUMP THE TRANSACTION LOG **********************************/
  4360.  
  4361.